根据自己项目需求调整代码中表达式的公共方法
using System.Collections;
using System.Collections.Generic;
using System;
using UnityEngine;
/// <summary>
/// 四则运算管理类
/// </summary>
public class FourArithmetic : Singleton<FourArithmetic>
{
#region 表达式方法
public string expression = "";
/// <summary>
/// 随机数加法表达式
/// </summary>
/// <param name="min"></param>
/// <param name="max"></param>
public void RandomNumAdd(int min, int max)
{
expression = "";
//System.Random ran = new System.Random();
//int n1 = ran.Next(min, max);
//int n2 = ran.Next(min, max);
int n1 = UnityEngine.Random.Range(min, max);
int n2 = UnityEngine.Random.Range(min, max);
if (n1 < 0) expression += "(" + n1 + ")";
else expression += n1;
expression += "+";
if (n2 < 0) expression += "(" + n2 + ")";
else expression += n2;
}
/// <summary>
/// 随机数减法表达式
/// </summary>
/// <param name="min"></param>
/// <param name="max"></param>
public void RandomNumMinus(int min, int max)
{
expression = "";
//System.Random ran = new System.Random();
//int n1 = ran.Next(min, max);
//int n2 = ran.Next(min, max);
int n1 = UnityEngine.Random.Range(min, max);
int n2 = UnityEngine.Random.Range(min, max);
if (n1 > n2)
{
if (n1 < 0) expression += "(" + n1 + ")";
else expression += n1;
expression += "-";
if (n2 < 0) expression += "(" + n2 + ")";
else expression += n2;
}
else
{
RandomNumMinus(min, max);
}
}
/// <summary>
/// 随机数乘法表达式
/// </summary>
/// <param name="min"></param>
/// <param name="max"></param>
public void RandomNumMultiply(int min, int max)
{
expression = "";
//System.Random ran = new System.Random();
//int n1 = ran.Next(min, max);
//int n2 = ran.Next(0, 3);
int n1, n2;
if (max > 10)
{
n1 = UnityEngine.Random.Range(min, max);
n2 = UnityEngine.Random.Range(1, 3);
}
else
{
n1 = UnityEngine.Random.Range(min, max);
n2 = UnityEngine.Random.Range(min, max);
}
if (n1 < 0) expression += "(" + n1 + ")";
else expression += n1;
expression += "*";
if (n2 < 0) expression += "(" + n2 + ")";
else expression += n2;
}
/// <summary>
/// 随机数除法表达式
/// </summary>
public void RandomNumDivide(int min, int max)
{
expression = "";
//System.Random ran = new System.Random();
//int n1 = ran.Next(min, max);
//int n2 = ran.Next(min, max);
int n1 = UnityEngine.Random.Range(min, max);
int n2 = UnityEngine.Random.Range(1, 10);
if (n1 < 0) expression += "(" + n1 + ")";
else expression += n1;
expression += "/";
if (n2 < 0) expression += "(" + n2 + ")";
else expression += n2;
}
/// <summary>
/// 三个数以上四则运算混合计算表达式
/// </summary>
/// <param name="select">选择对应的表达式</param>
/// <param name="min"></param>
/// <param name="max"></param>
public void MixedCalculation(int select, int min, int max)
{
System.Random ran = new System.Random();
//int n1, n2;
expression = "";
switch (select)
{
case 0://带括号三个数字的混合计算
{
int n1 = ran.Next(min, max);
int n2 = ran.Next(min, max);
int n3 = ran.Next(1, 3);
expression += "(";
if (n1 < 0) expression += "(" + n1 + ")";
else expression += n1;
if (ran.Next(0, 2) == 1) expression += "+";
else expression += "-";
if (n2 < 0) expression += "(" + n2 + ")";
else expression += n2 + ")";
expression += "*" + n3;
break;
}
case 2: //三个数字的加减混合表达式
{
int n1 = ran.Next(min, max);
int n2 = ran.Next(min, max);
int n3 = ran.Next(min, max);
expression += n1;
AddAndMinuMix(n2);
AddAndMinuMix(n3);
break;
}
case 3: //三个数字的混合计算
{
int n1 = ran.Next(min, max);
int n2 = ran.Next(min, max);
int n3 = ran.Next(min, max);
expression += n1;
AddMinusMultiplyMix(n2);
AddMinusMultiplyMix(n3);
break;
}
case 4: //四个数字的混合计算
{
int n1 = ran.Next(min, max);
int n2 = ran.Next(min, max);
int n3 = ran.Next(min, max);
int n4 = ran.Next(min, max);
expression += n1;
AddMinusMultiplyMix(n2);
AddMinusMultiplyMix(n3);
AddMinusMultiplyMix(n4);
break;
}
case 5: //五个数字的混合计算
{
int n1 = ran.Next(min, max);
int n2 = ran.Next(min, max);
int n3 = ran.Next(min, max);
int n4 = ran.Next(min, max);
int n5 = ran.Next(min, max);
expression += n1;
AddMinusMultiplyMix(n2);
AddMinusMultiplyMix(n3);
AddMinusMultiplyMix(n4);
AddMinusMultiplyMix(n5);
break;
}
default:
break;
}
}
/// <summary>
/// 加减混合表达式
/// </summary>
/// <param name="nextNum"></param>
private void AddAndMinuMix(int nextNum)
{
int random = UnityEngine.Random.Range(0, 2);
if (random.Equals(0))
{
expression += "+";
}
else if (random.Equals(1))
{
expression += "-";
}
expression += nextNum;
}
/// <summary>
/// 加减乘混合表达式
/// </summary>
/// <param name="nextNum"></param>
private void AddMinusMultiplyMix(int nextNum)
{
//System.Random ran = new System.Random();
//if (ran.Next(0, 3) == 0)
//{
// expression += "+";
//}
//else if (ran.Next(0, 3) == 1)
//{
// expression += "-";
//}
//else
//{
// nextNum = ran.Next(1, 3);//重新随机
// expression += "*";
//}
int random = UnityEngine.Random.Range(0, 3);
if (random.Equals(0))
{
expression += "+";
}
else if (random.Equals(1))
{
expression += "-";
}
else
{
nextNum = UnityEngine.Random.Range(1, 3);
expression += "*";
}
expression += nextNum;
}
/// <summary>
/// 四则运算混合表达式
/// </summary>
/// <param name="nextNum"></param>
private void FourArithmeticMix(int nextNum)
{
int random = UnityEngine.Random.Range(0, 4);
if (random.Equals(0))
{
expression += "+";
}
else if (random.Equals(1))
{
expression += "-";
}
else if (random.Equals(2))
{
nextNum = UnityEngine.Random.Range(1, 3);
expression += "*";
}
else if (random.Equals(3))
{
nextNum = UnityEngine.Random.Range(1, 10);
expression += "/";
}
expression += nextNum;
}
#endregion
#region 计算表达式
private Dictionary<char, int> priorities = new Dictionary<char, int> { { '#', -1 }, { '+', 0 }, { '-', 0 }, { '*', 1 }, { '/', 1 } }; //优先级
// private Dictionary<char, int> priorities = null;
/// <summary>
/// 初始化运算符优先级
/// </summary>
public void InitPriorities() //添加了四种运算符以及四种运算符的优先级
{
//priorities = new Dictionary<char, int>();
//priorities.Add('#', -1);
//priorities.Add('+', 0);
//priorities.Add('-', 0);
//priorities.Add('*', 1);
//priorities.Add('/', 1);
}
/// <summary>
/// 计算表达式
/// </summary>
/// <param name="expression"></param>
/// <returns></returns>
public double Calcuate()
{
try
{
var rpn = QueueSort(expression); //rpn逆波兰表达式reverse polish notation
Stack<double> operandStack = new Stack<double>();
double left, right;
object cur;
while (rpn.Count > 0)
{
cur = rpn.Dequeue(); //出列
if (cur is char) //如果cur为字符的话
{
right = operandStack.Pop(); //右边的数字出栈
left = operandStack.Pop(); //左边的数字出栈
//Debug.Log("左:" + left + "右:" + right + "现在的字符:" + cur);
operandStack.Push(Compute(left, right, (char)cur)); //此时调用compute方法
}
else
{
operandStack.Push(double.Parse(cur.ToString())); //是数字就压栈
}
}
return operandStack.Pop();
}
catch
{
Debug.LogError("表达式格式不正确!");
throw new Exception("表达式格式不正确!");
}
}
/// <summary>
/// 队列排序
/// </summary>
/// <param name="expression"></param>
/// <returns></returns>
private Queue<object> QueueSort(string expression) // 队列排序
{
Queue<object> result = new Queue<object>();
Stack<char> operatorStack = new Stack<char>(); //运算符栈
operatorStack.Push('#');
char top, cur, tempChar; //top栈顶,current最近的;
string tempNum;
for (int i = 0, j; i < expression.Length;) //取出表达式
{
cur = expression[i++]; //取出表达式的每个字符赋给cur
top = operatorStack.Peek(); //栈顶元素赋给top此时为"#"
if (cur == '(') //将左括号压栈,此时栈顶元素为"("
{
operatorStack.Push(cur);
}
else
{
if (IsOperator(cur)) //如果是运算符的话
{
while (IsOperator(top) && ((IsAssoc(cur) && priorities[cur] <= priorities[top])) || (!IsAssoc(cur) && priorities[cur] < priorities[top]))
{
result.Enqueue(operatorStack.Pop()); //如果元素为运算符并且优先级小于栈顶元素优先级,出栈
top = operatorStack.Peek(); //继续把栈顶元素赋给top
}
operatorStack.Push(cur); //把数字压栈
}
else if (cur == ')') //将右括号添加到结尾
{
while (operatorStack.Count > 0 && (tempChar = operatorStack.Pop()) != '(')
{
result.Enqueue(tempChar);
}
}
else
{
tempNum = "" + cur;
j = i;
while (j < expression.Length && (expression[j] == '.' || (expression[j] >= '0' && expression[j] <= '9')))
{
tempNum += expression[j++];
}
i = j;
result.Enqueue(tempNum);
}
}
}
while (operatorStack.Count > 0)
{
cur = operatorStack.Pop();
if (cur == '#') continue;
if (operatorStack.Count > 0)
{
top = operatorStack.Peek();
}
result.Enqueue(cur);
}
return result;
}
const string operators = "+-*/"; //运算符
/// <summary>
/// 计算左右两个数的方法
/// </summary>
/// <param name="leftNum"></param>
/// <param name="rightNum"></param>
/// <param name="op"></param>
/// <returns></returns>
private double Compute(double leftNum, double rightNum, char op) //这是一种方法,用来计算左右两个数的静态方法!
{
switch (op)
{
case '+': return leftNum + rightNum;
case '-': return leftNum - rightNum;
case '*': return leftNum * rightNum;
case '/': return leftNum / rightNum;
default: return 0;
}
}
/// <summary>
/// 判断这个字符是否是运算符?
/// </summary>
/// <param name="op"></param>
/// <returns></returns>
private bool IsOperator(char op) //每次判断这个字符是否是运算符?
{
return operators.IndexOf(op) >= 0;
}
/// <summary>
/// 返回一个关联符号
/// </summary>
/// <param name="op"></param>
/// <returns></returns>
private bool IsAssoc(char op) //返回一个关联符号
{
return op == '+' || op == '-' || op == '*' || op == '/';
}
#endregion
}