整体思路
就是直接处理字符串,添加或者删除。处理结果时,则以运算符为分隔,处理为字符串数组,然后根据优先级,进行计算,遍历到没有运算符为止。
效果:
代码:
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Calculator : MonoBehaviour
{
private readonly List<string> operators = new List<string>() { "×", "÷", "+", "-" };
private List<Button> buttons = new List<Button>();
private Text textDisplay;
private bool isEndofOperators = false;//是否以运算符结尾
private bool isHavePoint = false;
private List<string> elements = new List<string>();
private void Reset()
{
textDisplay.text = string.Empty;
isEndofOperators = false;
isHavePoint = false;
elements.Clear();
}
private void Awake()
{
buttons.AddRange(transform.GetComponentsInChildren<Button>());
textDisplay = transform.GetComponentInChildren<Text>();
}
private void Start()
{
for (int i = 0; i < buttons.Count; i++)
{
Button btn = buttons[i];
btn.onClick.AddListener(delegate
{
if (btn.name == "c")//清空
{
Reset();
return;
}
if (btn.name == "←")//删除一个字符
{
if (textDisplay.text != "")
{
if (textDisplay.text[textDisplay.text.Length - 1] == '.')
{
isHavePoint = false;
}
textDisplay.text = textDisplay.text.Remove(textDisplay.text.Length - 1);
}
isEndofOperators = textDisplay.text != string.Empty && operators.Contains(textDisplay.text[textDisplay.text.Length - 1].ToString());
return;
}
if (btn.name == "=")//计算
{
DoCalculator();
isEndofOperators = false;
isHavePoint = false;
elements.Clear();
return;
}
if (btn.name == ".")
{
if (isHavePoint) return;
if (isEndofOperators || textDisplay.text == string.Empty)//自动补0
{
textDisplay.text += "0";
}
isHavePoint = true;
}
if (isEndofOperators)//以字符结尾
{
if (operators.Contains(btn.name))
{
textDisplay.text = textDisplay.text.Remove(textDisplay.text.Length - 1);
textDisplay.text += btn.name;
return;
}
isEndofOperators = false;
}
isEndofOperators = operators.Contains(btn.name);
if (isEndofOperators) {
DoCalculator();
}
if (isEndofOperators)
{
isHavePoint = false;
}
if (textDisplay.text == string.Empty && isEndofOperators)
{
isEndofOperators = false;
return;
}
textDisplay.text += btn.name;
});
}
}
/// <summary>
/// 计算
/// </summary>
private void DoCalculator()
{
if (textDisplay.text == string.Empty)
return;
try
{
int startIndex = 0;
elements.Clear();
if (operators.Contains(textDisplay.text[textDisplay.text.Length - 1].ToString()))
{
textDisplay.text = textDisplay.text.Remove(textDisplay.text.Length - 1);
}
for (int i = 0; i < textDisplay.text.Length; i++)
{
if (operators.Contains(textDisplay.text[i].ToString()) && i != 0)
{
elements.Add(textDisplay.text.Substring(startIndex, i - startIndex));
elements.Add(textDisplay.text[i].ToString());
startIndex = i + 1;
}
}
elements.Add(textDisplay.text.Substring(startIndex, textDisplay.text.Length - startIndex));
if (operators.Contains(elements[elements.Count - 1]))
{
elements.RemoveAt(elements.Count - 1);
}
for (int i = 0; i < operators.Count; i++)
{
for (int j = 0; j < elements.Count; j++)
{
if (operators[i] == elements[j])
{
GetResult(
j,
d =>
{
for (int k = 0; k <= 2; k++)
{
elements.RemoveAt(j - 1);
}
elements.Insert(j - 1, d.ToString());
},
() =>
{
Debug.LogError("除数不能为0");
textDisplay.text = string.Empty;
return;
}
);
}
}
}
textDisplay.text = elements[0];
}
catch (Exception)
{
Debug.LogError("Error");
Reset();
}
}
private void GetResult(int id, Action<double> callback, Action error)
{
double result = 0;
bool isTrue = true;
switch (elements[id])
{
case "+":
result = double.Parse(elements[id - 1]) + double.Parse(elements[id + 1]);
break;
case "-":
if (elements[id - 1] == "")
{
elements[id - 1] = "0";
}
result = double.Parse(elements[id - 1]) - double.Parse(elements[id + 1]);
break;
case "×":
result = double.Parse(elements[id - 1]) * double.Parse(elements[id + 1]);
break;
case "÷":
if (elements[id + 1] == "0")
{
isTrue = false;
break;
}
result = double.Parse(elements[id - 1]) / double.Parse(elements[id + 1]);
break;
}
if (isTrue)
{
callback?.Invoke(result);
}
else
{
error?.Invoke();
}
}
}