随机生成四则运算表达式【Unity】
根据自己项目需求调整代码中表达式的公共方法
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 }