基于Unity制作一个简易的计算器
一、前言
Hello,又见面了,今天分享如何使用Unity制作计算器,难度中等,可以用来学习,或者当成其他项目的小组件导入。
当然,也可以导出来,发布到网页端,来做一个嵌入式工具也可以。
二、效果图及源工程
效果图:
三、实现
1.界面搭建
所有的按钮摆放到Background下面。
2.代码实现
首先找到所有的按钮,添加到事件:
//结果显示 TextComputeProcess = GameObject.Find("Canvas/Background/Image/TextComputeProcess").GetComponent<Text>(); TextComputeResult = GameObject.Find("Canvas/Background/Image/TextComputeResult").GetComponent<Text>(); TextComputeResult.text = "0"; RUNSTATE = 0; //操作 BtnReset = GameObject.Find("Canvas/Background/重置").GetComponent<Button>(); BtnReset.onClick.AddListener(() => OperationDispose("CE")); BtnDelete = GameObject.Find("Canvas/Background/删除").GetComponent<Button>(); BtnDelete.onClick.AddListener(() => OperationDispose("Del")); //加减乘除 BtnAdd = GameObject.Find("Canvas/Background/加").GetComponent<Button>(); BtnAdd.onClick.AddListener(() => OperationDispose("+")); BtnSub = GameObject.Find("Canvas/Background/减").GetComponent<Button>(); BtnSub.onClick.AddListener(() => OperationDispose("-")); BtnMul = GameObject.Find("Canvas/Background/乘").GetComponent<Button>(); BtnMul.onClick.AddListener(() => OperationDispose("*")); BtnDiv = GameObject.Find("Canvas/Background/除").GetComponent<Button>(); BtnDiv.onClick.AddListener(() => OperationDispose("/")); BtnEqual = GameObject.Find("Canvas/Background/等于").GetComponent<Button>(); BtnEqual.onClick.AddListener(() => OperationDispose("=")); //数字 Btn0 = GameObject.Find("Canvas/Background/0").GetComponent<Button>(); Btn0.onClick.AddListener(() => NumDispose("0")); Btn1 = GameObject.Find("Canvas/Background/1").GetComponent<Button>(); Btn1.onClick.AddListener(() => NumDispose("1")); Btn2 = GameObject.Find("Canvas/Background/2").GetComponent<Button>(); Btn2.onClick.AddListener(() => NumDispose("2")); Btn3 = GameObject.Find("Canvas/Background/3").GetComponent<Button>(); Btn3.onClick.AddListener(() => NumDispose("3")); Btn4 = GameObject.Find("Canvas/Background/4").GetComponent<Button>(); Btn4.onClick.AddListener(() => NumDispose("4")); Btn5 = GameObject.Find("Canvas/Background/5").GetComponent<Button>(); Btn5.onClick.AddListener(() => NumDispose("5")); Btn6 = GameObject.Find("Canvas/Background/6").GetComponent<Button>(); Btn6.onClick.AddListener(() => NumDispose("6")); Btn7 = GameObject.Find("Canvas/Background/7").GetComponent<Button>(); Btn7.onClick.AddListener(() => NumDispose("7")); Btn8 = GameObject.Find("Canvas/Background/8").GetComponent<Button>(); Btn8.onClick.AddListener(() => NumDispose("8")); Btn9 = GameObject.Find("Canvas/Background/9").GetComponent<Button>(); Btn9.onClick.AddListener(() => NumDispose("9")); BtnPoint = GameObject.Find("Canvas/Background/点").GetComponent<Button>(); BtnPoint.onClick.AddListener(() => NumDispose(".")); BtnPm = GameObject.Find("Canvas/Background/正负").GetComponent<Button>(); BtnPm.onClick.AddListener(() => NumDispose("-"));
按钮操作:
//操作点击处理 private void OperationDispose(string operation) { switch (operation) { case "+": if (RUNSTATE == 0) TextComputeProcess.text = "0 + "; else { TextComputeProcess.text = TextComputeResult.text + " + "; m_operation = "+"; RUNSTATE = 2; } break; case "-": if (RUNSTATE == 0) TextComputeProcess.text = "0 - "; else { TextComputeProcess.text = TextComputeResult.text + " - "; m_operation = "-"; RUNSTATE = 2; } break; case "*": if (RUNSTATE == 0) TextComputeProcess.text = "0 * "; else { TextComputeProcess.text = TextComputeResult.text + " * "; m_operation = "*"; RUNSTATE = 2; } break; case "/": if (RUNSTATE == 0) TextComputeProcess.text = "0 / "; else { TextComputeProcess.text = TextComputeResult.text + " / "; m_operation = "/"; RUNSTATE = 2; } break; case "=": if (RUNSTATE == 0) TextComputeProcess.text = "0 = "; else { if (RUNSTATE == 3) { double result; switch (m_operation) { case "+": result = double.Parse(calculateString) + double.Parse(TextComputeResult.text); TextComputeProcess.text = calculateString + " + " + TextComputeResult.text + " = "; TextComputeResult.text = result.ToString(); RUNSTATE = 4; break; case "-": result = double.Parse(calculateString) - double.Parse(TextComputeResult.text); TextComputeProcess.text = calculateString + " - " + TextComputeResult.text + " = "; TextComputeResult.text = result.ToString(); RUNSTATE = 4; break; case "*": result = double.Parse(calculateString) * double.Parse(TextComputeResult.text); TextComputeProcess.text = calculateString + " * " + TextComputeResult.text + " = "; TextComputeResult.text = result.ToString(); RUNSTATE = 4; break; case "/": result = double.Parse(calculateString) / double.Parse(TextComputeResult.text); TextComputeProcess.text = calculateString + " / " + TextComputeResult.text + " = "; TextComputeResult.text = result.ToString(); RUNSTATE = 4; break; default: break; } } else { TextComputeProcess.text = TextComputeResult.text + " = "; } } break; case "CE": TextComputeProcess.text = ""; TextComputeResult.text = "0"; RUNSTATE = 0; break; case "Del": if (RUNSTATE == 0) return; else { if (TextComputeResult.text.Length == 1) { TextComputeResult.text = "0"; } else { TextComputeResult.text = TextComputeResult.text.Remove(TextComputeResult.text.Length - 1, 1); } } break; default: break; } }
数字点击处理:
//数字点击处理 private void NumDispose(string num) { switch (num) { case ".": if (RUNSTATE == 0) TextComputeResult.text = "0"; else TextComputeResult.text += num; break; case "-": if (RUNSTATE == 0) TextComputeResult.text = "0"; else { if (RUNSTATE == 1) { if (pmState) { TextComputeResult.text = TextComputeResult.text.Remove(0, 1); pmState = false; } else { TextComputeResult.text = num + TextComputeResult.text; pmState = true; } } else if (RUNSTATE == 2) { pmState = false; } else if (RUNSTATE == 3) { if (pmState) { TextComputeResult.text = TextComputeResult.text.Remove(0, 1); pmState = false; } else { TextComputeResult.text = num + TextComputeResult.text; pmState = true; } } else if (RUNSTATE == 4) { pmState = false; OperationDispose("CE"); } } break; default: if (RUNSTATE == 0) { TextComputeResult.text = num; RUNSTATE = 1; } else if (RUNSTATE == 1) { pmState = false; TextComputeResult.text += num; } else if (RUNSTATE == 2) { calculateString = TextComputeResult.text; TextComputeResult.text = ""; TextComputeResult.text += num; RUNSTATE = 3; } else if (RUNSTATE == 3) { TextComputeResult.text += num; } else if (RUNSTATE == 4) { OperationDispose("CE"); TextComputeResult.text = num; RUNSTATE = 1; } break; } }
完整代码:
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class CalculatorControl : MonoBehaviour { private Text TextComputeProcess;//计算过程 private Text TextComputeResult;//计算结果 private Button BtnReset; private Button BtnDelete; private Button BtnAdd; private Button BtnSub; private Button BtnMul; private Button BtnDiv; private Button BtnEqual; private Button Btn0, Btn1, Btn2, Btn3, Btn4, Btn5, Btn6, Btn7, Btn8, Btn9; private Button BtnPoint, BtnPm; private string calculateString = "";//计算数 private string m_operation = "";//操作数 private bool pmState = false;//正负状态 private int RUNSTATE = 0;//0 默认 1 输入数字 2 输入操作符 3 输入操作符再输入数字 4 计算结果后 void Start() { //结果显示 TextComputeProcess = GameObject.Find("Canvas/Background/Image/TextComputeProcess").GetComponent<Text>(); TextComputeResult = GameObject.Find("Canvas/Background/Image/TextComputeResult").GetComponent<Text>(); TextComputeResult.text = "0"; RUNSTATE = 0; //操作 BtnReset = GameObject.Find("Canvas/Background/重置").GetComponent<Button>(); BtnReset.onClick.AddListener(() => OperationDispose("CE")); BtnDelete = GameObject.Find("Canvas/Background/删除").GetComponent<Button>(); BtnDelete.onClick.AddListener(() => OperationDispose("Del")); //加减乘除 BtnAdd = GameObject.Find("Canvas/Background/加").GetComponent<Button>(); BtnAdd.onClick.AddListener(() => OperationDispose("+")); BtnSub = GameObject.Find("Canvas/Background/减").GetComponent<Button>(); BtnSub.onClick.AddListener(() => OperationDispose("-")); BtnMul = GameObject.Find("Canvas/Background/乘").GetComponent<Button>(); BtnMul.onClick.AddListener(() => OperationDispose("*")); BtnDiv = GameObject.Find("Canvas/Background/除").GetComponent<Button>(); BtnDiv.onClick.AddListener(() => OperationDispose("/")); BtnEqual = GameObject.Find("Canvas/Background/等于").GetComponent<Button>(); BtnEqual.onClick.AddListener(() => OperationDispose("=")); //数字 Btn0 = GameObject.Find("Canvas/Background/0").GetComponent<Button>(); Btn0.onClick.AddListener(() => NumDispose("0")); Btn1 = GameObject.Find("Canvas/Background/1").GetComponent<Button>(); Btn1.onClick.AddListener(() => NumDispose("1")); Btn2 = GameObject.Find("Canvas/Background/2").GetComponent<Button>(); Btn2.onClick.AddListener(() => NumDispose("2")); Btn3 = GameObject.Find("Canvas/Background/3").GetComponent<Button>(); Btn3.onClick.AddListener(() => NumDispose("3")); Btn4 = GameObject.Find("Canvas/Background/4").GetComponent<Button>(); Btn4.onClick.AddListener(() => NumDispose("4")); Btn5 = GameObject.Find("Canvas/Background/5").GetComponent<Button>(); Btn5.onClick.AddListener(() => NumDispose("5")); Btn6 = GameObject.Find("Canvas/Background/6").GetComponent<Button>(); Btn6.onClick.AddListener(() => NumDispose("6")); Btn7 = GameObject.Find("Canvas/Background/7").GetComponent<Button>(); Btn7.onClick.AddListener(() => NumDispose("7")); Btn8 = GameObject.Find("Canvas/Background/8").GetComponent<Button>(); Btn8.onClick.AddListener(() => NumDispose("8")); Btn9 = GameObject.Find("Canvas/Background/9").GetComponent<Button>(); Btn9.onClick.AddListener(() => NumDispose("9")); BtnPoint = GameObject.Find("Canvas/Background/点").GetComponent<Button>(); BtnPoint.onClick.AddListener(() => NumDispose(".")); BtnPm = GameObject.Find("Canvas/Background/正负").GetComponent<Button>(); BtnPm.onClick.AddListener(() => NumDispose("-")); } //操作点击处理 private void OperationDispose(string operation) { switch (operation) { case "+": if (RUNSTATE == 0) TextComputeProcess.text = "0 + "; else { TextComputeProcess.text = TextComputeResult.text + " + "; m_operation = "+"; RUNSTATE = 2; } break; case "-": if (RUNSTATE == 0) TextComputeProcess.text = "0 - "; else { TextComputeProcess.text = TextComputeResult.text + " - "; m_operation = "-"; RUNSTATE = 2; } break; case "*": if (RUNSTATE == 0) TextComputeProcess.text = "0 * "; else { TextComputeProcess.text = TextComputeResult.text + " * "; m_operation = "*"; RUNSTATE = 2; } break; case "/": if (RUNSTATE == 0) TextComputeProcess.text = "0 / "; else { TextComputeProcess.text = TextComputeResult.text + " / "; m_operation = "/"; RUNSTATE = 2; } break; case "=": if (RUNSTATE == 0) TextComputeProcess.text = "0 = "; else { if (RUNSTATE == 3) { double result; switch (m_operation) { case "+": result = double.Parse(calculateString) + double.Parse(TextComputeResult.text); TextComputeProcess.text = calculateString + " + " + TextComputeResult.text + " = "; TextComputeResult.text = result.ToString(); RUNSTATE = 4; break; case "-": result = double.Parse(calculateString) - double.Parse(TextComputeResult.text); TextComputeProcess.text = calculateString + " - " + TextComputeResult.text + " = "; TextComputeResult.text = result.ToString(); RUNSTATE = 4; break; case "*": result = double.Parse(calculateString) * double.Parse(TextComputeResult.text); TextComputeProcess.text = calculateString + " * " + TextComputeResult.text + " = "; TextComputeResult.text = result.ToString(); RUNSTATE = 4; break; case "/": result = double.Parse(calculateString) / double.Parse(TextComputeResult.text); TextComputeProcess.text = calculateString + " / " + TextComputeResult.text + " = "; TextComputeResult.text = result.ToString(); RUNSTATE = 4; break; default: break; } } else { TextComputeProcess.text = TextComputeResult.text + " = "; } } break; case "CE": TextComputeProcess.text = ""; TextComputeResult.text = "0"; RUNSTATE = 0; break; case "Del": if (RUNSTATE == 0) return; else { if (TextComputeResult.text.Length == 1) { TextComputeResult.text = "0"; } else { TextComputeResult.text = TextComputeResult.text.Remove(TextComputeResult.text.Length - 1, 1); } } break; default: break; } } //数字点击处理 private void NumDispose(string num) { switch (num) { case ".": if (RUNSTATE == 0) TextComputeResult.text = "0"; else TextComputeResult.text += num; break; case "-": if (RUNSTATE == 0) TextComputeResult.text = "0"; else { if (RUNSTATE == 1) { if (pmState) { TextComputeResult.text = TextComputeResult.text.Remove(0, 1); pmState = false; } else { TextComputeResult.text = num + TextComputeResult.text; pmState = true; } } else if (RUNSTATE == 2) { pmState = false; } else if (RUNSTATE == 3) { if (pmState) { TextComputeResult.text = TextComputeResult.text.Remove(0, 1); pmState = false; } else { TextComputeResult.text = num + TextComputeResult.text; pmState = true; } } else if (RUNSTATE == 4) { pmState = false; OperationDispose("CE"); } } break; default: if (RUNSTATE == 0) { TextComputeResult.text = num; RUNSTATE = 1; } else if (RUNSTATE == 1) { pmState = false; TextComputeResult.text += num; } else if (RUNSTATE == 2) { calculateString = TextComputeResult.text; TextComputeResult.text = ""; TextComputeResult.text += num; RUNSTATE = 3; } else if (RUNSTATE == 3) { TextComputeResult.text += num; } else if (RUNSTATE == 4) { OperationDispose("CE"); TextComputeResult.text = num; RUNSTATE = 1; } break; } } }
效果图如下:
四、后记
完整代码278行,还是依旧那么简练,整体代码难度不大,主要是状态之间的切换:
1、输入数字的状态
2、输入操作符状态
3、输入操作符后再输入数字状态
4、计算结果后状态
理解这些状态后,代码就容易理解了。
最后,拓展一下,将其他大佬写的代码给大家看一下,大家如果觉得上面的代码太简单,可以看一下:
代码使用OnGUI搭建界面,直接拖到任意对象上就可以看到效果了:
using UnityEngine; using System.Text.RegularExpressions; using System; public class Calculator2 : MonoBehaviour { public static bool IsNumeric(string value) { return Regex.IsMatch(value, @"^[+-]?\d*[.]?\d*$"); } public string result = "";//用来显示结果 public static string str1 = "";//第一个操作数 public static bool haveDot = false;//第二个操作数 public static bool isCaclutate = false; void OnGUI() { //对数字进行处理 if (GUI.Button(new Rect(100, 100, 100, 60), "CE")) { result = ""; str1 = ""; haveDot = false; } if (GUI.Button(new Rect(210, 100, 100, 60), "×") && str1.Substring(str1.Length - 1, 1) != "-" && str1.Substring(str1.Length - 1, 1) != "+" && str1.Substring(str1.Length - 1, 1) != ".") { if (IsNumeric(str1.Substring(str1.Length - 1, 1))) { Debug.Log(str1.Substring(str1.Length - 1, 1)); str1 += "*"; haveDot = false; isCaclutate = false; } result = str1; } if (GUI.Button(new Rect(320, 100, 100, 60), "÷") && str1.Substring(str1.Length - 1, 1) != "-" && str1.Substring(str1.Length - 1, 1) != "+" && str1.Substring(str1.Length - 1, 1) != ".") { if (IsNumeric(str1.Substring(str1.Length - 1, 1))) { str1 += "/"; haveDot = false; isCaclutate = false; } result = str1; } if (GUI.Button(new Rect(430, 100, 100, 60), "←")) { if (isCaclutate == true) { str1 = ""; isCaclutate = false; } else if (result.Length != 0) { str1 = str1.Substring(0, str1.Length - 1); } result = str1; } if (GUI.Button(new Rect(100, 170, 100, 60), "1")) { if (isCaclutate == true) { str1 = ""; isCaclutate = false; haveDot = false; } str1 += "1"; result = str1; } if (GUI.Button(new Rect(210, 170, 100, 60), "2")) { if (isCaclutate == true) { str1 = ""; isCaclutate = false; haveDot = false; } str1 += "2"; result = str1; } if (GUI.Button(new Rect(320, 170, 100, 60), "3")) { if (isCaclutate == true) { str1 = ""; isCaclutate = false; haveDot = false; } str1 += "3"; result = str1; } if (GUI.Button(new Rect(430, 170, 100, 60), "-")) { if (IsNumeric(str1.Substring(str1.Length - 1, 1)) && str1.Substring(str1.Length - 1, 1) != "-" && str1.Substring(str1.Length - 1, 1) != "+" && str1.Substring(str1.Length - 1, 1) != ".") { str1 += "-"; haveDot = false; isCaclutate = false; } result = str1; } if (GUI.Button(new Rect(100, 240, 100, 60), "4")) { if (isCaclutate == true) { str1 = ""; isCaclutate = false; haveDot = false; } str1 += "4"; result = str1; } if (GUI.Button(new Rect(210, 240, 100, 60), "5")) { if (isCaclutate == true) { str1 = ""; isCaclutate = false; haveDot = false; } str1 += "5"; result = str1; } if (GUI.Button(new Rect(320, 240, 100, 60), "6")) { if (isCaclutate == true) { str1 = ""; isCaclutate = false; haveDot = false; } str1 += "6"; result = str1; } if (GUI.Button(new Rect(430, 240, 100, 60), "+") && str1.Substring(str1.Length - 1, 1) != "+" && str1.Substring(str1.Length - 1, 1) != "-" && str1.Substring(str1.Length - 1, 1) != ".") { if (IsNumeric(str1.Substring(str1.Length - 1, 1))) { str1 += "+"; haveDot = false; isCaclutate = false; } result = str1; } if (GUI.Button(new Rect(100, 310, 100, 60), "7")) { if (isCaclutate == true) { str1 = ""; isCaclutate = false; haveDot = false; } str1 += "7"; result = str1; } if (GUI.Button(new Rect(210, 310, 100, 60), "8")) { if (isCaclutate == true) { str1 = ""; isCaclutate = false; haveDot = false; } str1 += "8"; result = str1; } if (GUI.Button(new Rect(320, 310, 100, 60), "9")) { if (isCaclutate == true) { str1 = ""; isCaclutate = false; haveDot = false; } str1 += "9"; result = str1; } if (GUI.Button(new Rect(430, 310, 100, 130), "=")) { var tmp = Evaluator.Eval(result); Debug.Log(tmp.ToString()); result = tmp.ToString(); str1 = result; isCaclutate = true; if (result.Contains(".")) { haveDot = true; } } if (GUI.Button(new Rect(100, 380, 210, 60), "0")) { if (isCaclutate == true) { str1 = ""; isCaclutate = false; haveDot = false; } str1 += "0"; result = str1; } if (GUI.Button(new Rect(320, 380, 100, 60), ".")) { if (isCaclutate == true) { str1 = "0."; isCaclutate = false; } if (IsNumeric(str1.Substring(str1.Length - 1, 1)) && str1.Substring(str1.Length - 1, 1) != "." && haveDot == false) { Debug.Log(str1.Substring(str1.Length - 1, 1)); str1 += "."; haveDot = true; isCaclutate = false; } result = str1; } GUI.TextArea(new Rect(100, 20, 430, 60), result); } /**/ /// <summary> /// 动态求值 /// </summary> public class Evaluator { /**/ /// <summary> /// 计算结果,如果表达式出错则抛出异常 /// </summary> /// <param name="statement">表达式,如"1+2+3+4"</param> /// <returns>结果</returns> public static object Eval(string statement) { if (statement.Trim() != string.Empty) { Evaluator evaluator = new Evaluator(); return evaluator.GetFormulaResult(statement); } else { return null; } } private object GetFormulaResult(string s) { if (s == "") { return null; } string S = BuildingRPN(s); string tmp = ""; System.Collections.Stack sk = new System.Collections.Stack(); char c = ' '; System.Text.StringBuilder Operand = new System.Text.StringBuilder(); double x, y; for (int i = 0; i < S.Length; i++) { c = S[i]; //added c==',' for germany culture if (char.IsDigit(c) || c == '.' || c == ',') { //数据值收集. Operand.Append(c); } else if (c == ' ' && Operand.Length > 0) { #region 运算数转换 try { tmp = Operand.ToString(); if (tmp.StartsWith("-"))//负数的转换一定要小心...它不被直接支持. { //现在我的算法里这个分支可能永远不会被执行. sk.Push(-((double)Convert.ToDouble(tmp.Substring(1, tmp.Length - 1)))); } else { sk.Push(Convert.ToDouble(tmp)); } } catch { return null; // } Operand = new System.Text.StringBuilder(); #endregion } else if (c == '+'//运算符处理.双目运算处理. || c == '-' || c == '*' || c == '/' || c == '%' || c == '^') { #region 双目运算 if (sk.Count > 0)/*如果输入的表达式根本没有包含运算符.或是根本就是空串.这里的逻辑就有意义了.*/ { y = (double)sk.Pop(); } else { sk.Push(0); break; } if (sk.Count > 0) x = (double)sk.Pop(); else { sk.Push(y); break; } switch (c) { case '+': sk.Push(x + y); break; case '-': sk.Push(x - y); break; case '*': if (y == 0) { sk.Push(x * 1); } else { sk.Push(x * y); } break; case '/': if (y == 0) { sk.Push(x / 0); } else { sk.Push(x / y); } break; case '%': sk.Push(x % y); break; case '^':// if (x > 0)// { //我原本还想,如果被计算的数是负数,又要开真分数次方时如何处理的问题.后来我想还是算了吧. sk.Push(System.Math.Pow(x, y)); // } // else// { // double t = y; // string ts = ""; // t = 1 / (2 * t); // ts = t.ToString(); // if (ts.ToUpper().LastIndexOf('E') > 0)// { // ; // } // } break; } #endregion } else if (c == '!')//单目取反. ) { sk.Push(-((double)sk.Pop())); } } if (sk.Count > 1) { return null;//; } if (sk.Count == 0) { return null;//; } return sk.Pop(); } /**/ /// <summary> /// /// </summary> private string BuildingRPN(string s) { System.Text.StringBuilder sb = new System.Text.StringBuilder(s); System.Collections.Stack sk = new System.Collections.Stack(); System.Text.StringBuilder re = new System.Text.StringBuilder(); char c = ' '; //sb.Replace( " ","" ); //一开始,我只去掉了空格.后来我不想不支持函数和常量能滤掉的全OUT掉. for (int i = 0; i < sb.Length; i++) { c = sb[i]; //added c==',' for german culture if (char.IsDigit(c) || c == ',')//数字当然要了. re.Append(c); //if( char.IsWhiteSpace( c )|| char.IsLetter(c);//如果是空白,那么不要.现在字母也不要. //continue; switch (c)//如果是其它字符...列出的要,没有列出的不要. { case '+': case '-': case '*': case '/': case '%': case '^': case '!': case '(': case ')': case '.': re.Append(c); break; default: continue; } } sb = new System.Text.StringBuilder(re.ToString()); #region 对负号进行预转义处理.负号变单目运算符求反. for (int i = 0; i < sb.Length - 1; i++) if (sb[i] == '-' && (i == 0 || sb[i - 1] == '(')) sb[i] = '!'; //字符转义. #endregion #region 将中缀表达式变为后缀表达式. re = new System.Text.StringBuilder(); for (int i = 0; i < sb.Length; i++) { if (char.IsDigit(sb[i]) || sb[i] == '.')//如果是数值. { re.Append(sb[i]); //加入后缀式 } else if (sb[i] == '+' || sb[i] == '-' || sb[i] == '*' || sb[i] == '/' || sb[i] == '%' || sb[i] == '^' || sb[i] == '!')//. { #region 运算符处理 while (sk.Count > 0) //栈不为空时 { c = (char)sk.Pop(); //将栈中的操作符弹出. if (c == '(') //如果发现左括号.停. { sk.Push(c); //将弹出的左括号压回.因为还有右括号要和它匹配. break; //中断. } else { if (Power(c) < Power(sb[i]))//如果优先级比上次的高,则压栈. { sk.Push(c); break; } else { re.Append(' '); re.Append(c); } //如果不是左括号,那么将操作符加入后缀式中. } } sk.Push(sb[i]); //把新操作符入栈. re.Append(' '); #endregion } else if (sb[i] == '(')//基本优先级提升 { sk.Push('('); re.Append(' '); } else if (sb[i] == ')')//基本优先级下调 { while (sk.Count > 0) //栈不为空时 { c = (char)sk.Pop(); //pop Operator if (c != '(') { re.Append(' '); re.Append(c); //加入空格主要是为了防止不相干的数据相临产生解析错误. re.Append(' '); } else break; } } else re.Append(sb[i]); } while (sk.Count > 0)//这是最后一个弹栈啦. { re.Append(' '); re.Append(sk.Pop()); } #endregion re.Append(' '); return FormatSpace(re.ToString()); //在这里进行一次表达式格式化.这里就是后缀式了. } /// <summary> /// 优先级别测试函数. /// </summary> /// <param name="opr"></param> /// <returns></returns> private static int Power(char opr) { switch (opr) { case '+': case '-': return 1; case '*': case '/': return 2; case '%': case '^': case '!': return 3; default: return 0; } } /// <summary> /// 规范化逆波兰表达式. /// </summary> /// <param name="s"></param> /// <returns></returns> private static string FormatSpace(string s) { System.Text.StringBuilder ret = new System.Text.StringBuilder(); for (int i = 0; i < s.Length; i++) { if (!(s.Length > i + 1 && s[i] == ' ' && s[i + 1] == ' ')) ret.Append(s[i]); else ret.Append(s[i]); } return ret.ToString(); //.Replace( '!','-' ); } } }
到此这篇关于基于Unity制作一个简易的计算器的文章就介绍到这了,更多相关Unity计算器内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
最新评论