基于Unity制作一個簡易的計算器
一、前言
Hello,又見面了,今天分享如何使用Unity制作計算器,難度中等,可以用來學(xué)習(xí),或者當(dāng)成其他項(xiàng)目的小組件導(dǎo)入。
當(dāng)然,也可以導(dǎo)出來,發(fā)布到網(wǎng)頁端,來做一個嵌入式工具也可以。
二、效果圖及源工程
效果圖:

三、實(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;//計算過程
private Text TextComputeResult;//計算結(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 = "";//計算數(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 計算結(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、計算結(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 = "";//第一個操作數(shù)
public static bool haveDot = false;//第二個操作數(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>
/// 動態(tài)求值
/// </summary>
public class Evaluator
{
/**/
/// <summary>
/// 計算結(jié)果,如果表達(dá)式出錯則拋出異常
/// </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)在我的算法里這個分支可能永遠(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)//
{
//我原本還想,如果被計算的數(shù)是負(fù)數(shù),又要開真分?jǐn)?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) //棧不為空時
{
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) //棧不為空時
{
c = (char)sk.Pop();
//pop Operator
if (c != '(')
{
re.Append(' ');
re.Append(c);
//加入空格主要是為了防止不相干的數(shù)據(jù)相臨產(chǎn)生解析錯誤.
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());
//在這里進(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制作一個簡易的計算器的文章就介紹到這了,更多相關(guān)Unity計算器內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
c#實(shí)現(xiàn)字符串反序輸出字符串的實(shí)例
下面小編就為大家分享一篇c#實(shí)現(xiàn)字符串反序輸出字符串的實(shí)例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2017-12-12
c# 根據(jù)NPOI 讀取一個excel 文件的多個Sheet
這篇文章主要介紹了c# 根據(jù)NPOI 讀取一個excel 文件的多個Sheet,幫助大家更好的利用c#處理excel表格,感興趣的朋友可以了解下2020-12-12
C# DataTable與Model互轉(zhuǎn)的示例代碼
這篇文章主要介紹了C#DataTable與Model互轉(zhuǎn)的示例代碼,幫助大家更好的理解和使用c#,感興趣的朋友可以了解下2020-12-12
C# JavaScriptSerializer序列化時的時間處理詳解
這篇文章主要為大家詳細(xì)介紹了C# JavaScriptSerializer序列化時的時間處理詳解,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-08-08
winform 實(shí)現(xiàn)選擇文件和選擇文件夾對話框的簡單實(shí)例
下面小編就為大家?guī)硪黄獁inform 實(shí)現(xiàn)選擇文件和選擇文件夾對話框的簡單實(shí)例。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-01-01

