• 随机生成四则运算表达式【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
    }

    参考博客链接:https://www.cnblogs.com/thinking-star/p/4917349.html

  • 相关阅读:
    Optional类的基本使用(没怎么看)
    443. String Compression字符串压缩
    520. Detect Capital判断单词有效性
    521. Longest Uncommon Subsequence I 最长不同子数组
    459. Repeated Substring Pattern 判断数组是否由重复单元构成
    686. Repeated String Match 字符串重复后的子字符串查找
    696. Count Binary Substrings统计配对的01个数
    58. Length of Last Word最后一个单词的长度
    680. Valid Palindrome II 对称字符串-可删字母版本
    125. Valid Palindrome判断有效的有符号的回文串
  • 原文地址:https://www.cnblogs.com/Study088/p/15979197.html
Copyright © 2020-2023  润新知