基于Unity制作一個(gè)簡易的計(jì)算器
一、前言
Hello,又見面了,今天分享如何使用Unity制作計(jì)算器,難度中等,可以用來學(xué)習(xí),或者當(dāng)成其他項(xiàng)目的小組件導(dǎo)入。
當(dāng)然,也可以導(dǎo)出來,發(fā)布到網(wǎng)頁端,來做一個(gè)嵌入式工具也可以。
二、效果圖及源工程
效果圖:
三、實(shí)現(xiàn)
1.界面搭建
所有的按鈕擺放到Background下面。
2.代碼實(shí)現(xiàn)
首先找到所有的按鈕,添加到事件:
//結(jié)果顯示 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("=")); //數(shù)字 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/點(diǎn)").GetComponent<Button>(); BtnPoint.onClick.AddListener(() => NumDispose(".")); BtnPm = GameObject.Find("Canvas/Background/正負(fù)").GetComponent<Button>(); BtnPm.onClick.AddListener(() => NumDispose("-"));
按鈕操作:
//操作點(diǎn)擊處理 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; } }
數(shù)字點(diǎn)擊處理:
//數(shù)字點(diǎn)擊處理 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;//計(jì)算過程 private Text TextComputeResult;//計(jì)算結(jié)果 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 = "";//計(jì)算數(shù) private string m_operation = "";//操作數(shù) private bool pmState = false;//正負(fù)狀態(tài) private int RUNSTATE = 0;//0 默認(rèn) 1 輸入數(shù)字 2 輸入操作符 3 輸入操作符再輸入數(shù)字 4 計(jì)算結(jié)果后 void Start() { //結(jié)果顯示 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("=")); //數(shù)字 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/點(diǎn)").GetComponent<Button>(); BtnPoint.onClick.AddListener(() => NumDispose(".")); BtnPm = GameObject.Find("Canvas/Background/正負(fù)").GetComponent<Button>(); BtnPm.onClick.AddListener(() => NumDispose("-")); } //操作點(diǎn)擊處理 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; } } //數(shù)字點(diǎn)擊處理 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行,還是依舊那么簡練,整體代碼難度不大,主要是狀態(tài)之間的切換:
1、輸入數(shù)字的狀態(tài)
2、輸入操作符狀態(tài)
3、輸入操作符后再輸入數(shù)字狀態(tài)
4、計(jì)算結(jié)果后狀態(tài)
理解這些狀態(tài)后,代碼就容易理解了。
最后,拓展一下,將其他大佬寫的代碼給大家看一下,大家如果覺得上面的代碼太簡單,可以看一下:
代碼使用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 = "";//用來顯示結(jié)果 public static string str1 = "";//第一個(gè)操作數(shù) public static bool haveDot = false;//第二個(gè)操作數(shù) public static bool isCaclutate = false; void OnGUI() { //對數(shù)字進(jìn)行處理 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> /// 動(dòng)態(tài)求值 /// </summary> public class Evaluator { /**/ /// <summary> /// 計(jì)算結(jié)果,如果表達(dá)式出錯(cuò)則拋出異常 /// </summary> /// <param name="statement">表達(dá)式,如"1+2+3+4"</param> /// <returns>結(jié)果</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 == ',') { //數(shù)據(jù)值收集. Operand.Append(c); } else if (c == ' ' && Operand.Length > 0) { #region 運(yùn)算數(shù)轉(zhuǎn)換 try { tmp = Operand.ToString(); if (tmp.StartsWith("-"))//負(fù)數(shù)的轉(zhuǎn)換一定要小心...它不被直接支持. { //現(xiàn)在我的算法里這個(gè)分支可能永遠(yuǎn)不會被執(zhí)行. 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 == '+'//運(yùn)算符處理.雙目運(yùn)算處理. || c == '-' || c == '*' || c == '/' || c == '%' || c == '^') { #region 雙目運(yùn)算 if (sk.Count > 0)/*如果輸入的表達(dá)式根本沒有包含運(yùn)算符.或是根本就是空串.這里的邏輯就有意義了.*/ { 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)// { //我原本還想,如果被計(jì)算的數(shù)是負(fù)數(shù),又要開真分?jǐn)?shù)次方時(shí)如何處理的問題.后來我想還是算了吧. 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( " ","" ); //一開始,我只去掉了空格.后來我不想不支持函數(shù)和常量能濾掉的全OUT掉. for (int i = 0; i < sb.Length; i++) { c = sb[i]; //added c==',' for german culture if (char.IsDigit(c) || c == ',')//數(shù)字當(dāng)然要了. re.Append(c); //if( char.IsWhiteSpace( c )|| char.IsLetter(c);//如果是空白,那么不要.現(xiàn)在字母也不要. //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 對負(fù)號進(jìn)行預(yù)轉(zhuǎn)義處理.負(fù)號變單目運(yùn)算符求反. for (int i = 0; i < sb.Length - 1; i++) if (sb[i] == '-' && (i == 0 || sb[i - 1] == '(')) sb[i] = '!'; //字符轉(zhuǎn)義. #endregion #region 將中綴表達(dá)式變?yōu)楹缶Y表達(dá)式. re = new System.Text.StringBuilder(); for (int i = 0; i < sb.Length; i++) { if (char.IsDigit(sb[i]) || sb[i] == '.')//如果是數(shù)值. { re.Append(sb[i]); //加入后綴式 } else if (sb[i] == '+' || sb[i] == '-' || sb[i] == '*' || sb[i] == '/' || sb[i] == '%' || sb[i] == '^' || sb[i] == '!')//. { #region 運(yùn)算符處理 while (sk.Count > 0) //棧不為空時(shí) { c = (char)sk.Pop(); //將棧中的操作符彈出. if (c == '(') //如果發(fā)現(xiàn)左括號.停. { sk.Push(c); //將彈出的左括號壓回.因?yàn)檫€有右括號要和它匹配. break; //中斷. } else { if (Power(c) < Power(sb[i]))//如果優(yōu)先級比上次的高,則壓棧. { sk.Push(c); break; } else { re.Append(' '); re.Append(c); } //如果不是左括號,那么將操作符加入后綴式中. } } sk.Push(sb[i]); //把新操作符入棧. re.Append(' '); #endregion } else if (sb[i] == '(')//基本優(yōu)先級提升 { sk.Push('('); re.Append(' '); } else if (sb[i] == ')')//基本優(yōu)先級下調(diào) { while (sk.Count > 0) //棧不為空時(shí) { c = (char)sk.Pop(); //pop Operator if (c != '(') { re.Append(' '); re.Append(c); //加入空格主要是為了防止不相干的數(shù)據(jù)相臨產(chǎn)生解析錯(cuò)誤. re.Append(' '); } else break; } } else re.Append(sb[i]); } while (sk.Count > 0)//這是最后一個(gè)彈棧啦. { re.Append(' '); re.Append(sk.Pop()); } #endregion re.Append(' '); return FormatSpace(re.ToString()); //在這里進(jìn)行一次表達(dá)式格式化.這里就是后綴式了. } /// <summary> /// 優(yōu)先級別測試函數(shù). /// </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> /// 規(guī)范化逆波蘭表達(dá)式. /// </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( '!','-' ); } } }
到此這篇關(guān)于基于Unity制作一個(gè)簡易的計(jì)算器的文章就介紹到這了,更多相關(guān)Unity計(jì)算器內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C#實(shí)現(xiàn)獲取文件大小并進(jìn)行比較
這篇文章主要為大家詳細(xì)介紹了C#如何實(shí)現(xiàn)獲取文件大小進(jìn)行單位轉(zhuǎn)換與文件大小比較功能,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下2023-03-03C#中StringBuilder用法以及和String的區(qū)別分析
當(dāng)我們在初學(xué)使用C#時(shí),常常會不知道該用StringBuilder合適還是用String高效,下面是我在學(xué)習(xí)當(dāng)中對StringBuilder和String的區(qū)別總結(jié),分享給大家。2013-03-03Unity中的PostProcessScene實(shí)用案例深入解析
這篇文章主要為大家介紹了Unity中的PostProcessScene實(shí)用案例深入解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-05-05C#中數(shù)組Array,ArrayList,泛型List詳細(xì)對比
關(guān)于數(shù)組Array,ArrayList,泛型List,簡單的說數(shù)組就是值對象,它存儲數(shù)據(jù)元素類型的值的一系列位置.Arraylist和list可以提供添加,刪除,等操作的數(shù)據(jù). 具體如何進(jìn)行選擇使用呢,我們來詳細(xì)探討下2016-06-06C#對象為Null模式(Null Object Pattern)實(shí)例教程
這篇文章主要介紹了C#對象為Null模式(Null Object Pattern),以一個(gè)簡單實(shí)例深入分析了C#為Null情況下的處理方法,需要的朋友可以參考下2014-09-09使用DateTime的ParseExact方法實(shí)現(xiàn)特殊日期時(shí)間的方法詳解
本篇文章是對使用DateTime的ParseExact方法實(shí)現(xiàn)特殊日期時(shí)間的方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05