四则运算

Posted 袁玥

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了四则运算相关的知识,希望对你有一定的参考价值。

算法:
一、 将中缀表达式转换成后缀表达式算法:
1、从左至右扫描一中缀表达式。
2、若读取的是操作数,则判断该操作数的类型,并将该操作数存入操作数堆栈
3、若读取的是运算符
  (1) 该运算符为左括号"(",则直接存入运算符堆栈。
  (2) 该运算符为右括号")",则输出运算符堆栈中的运算符到操作数堆栈,直到遇到左括号为止。
  (3) 该运算符为非括号运算符:
      (a) 若运算符堆栈栈顶的运算符为括号,则直接存入运算符堆栈。
      (b) 若比运算符堆栈栈顶的运算符优先级高或相等,则直接存入运算符堆栈。
      (c) 若比运算符堆栈栈顶的运算符优先级低,则输出栈顶运算符到操作数堆栈,并将当前运算符压入运算符堆栈。
4、当表达式读取完成后运算符堆栈中尚有运算符时,则依序取出运算符到操作数堆栈,直到运算符堆栈为空。
 
二、逆波兰表达式求值算法:

      对后缀表达式求值比直接对中缀表达式求值简单。在后缀表达式中,不需要括号,而且操作符的优先级也不再起作用了。可以用如下算法对后缀表达式求值:

  1. 初始化一个空堆栈
  2. 从左到右读入后缀表达式
  3. 如果字符是一个操作数,把它压入堆栈。
  4. 如果字符是个操作符,弹出两个操作数,执行恰当操作,然后把结果压入堆栈。如果您不能够弹出两个操作数,后缀表达式的语法就不正确。
  5. 到后缀表达式末尾,从堆栈中弹出结果。若后缀表达式格式正确,那么堆栈应该为空。 

功能一的实现:

参考了一个博客:计划写出3个主函数来实现这个功能,今天先写了一些其余的小函数:

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

//author: yy
//time:17/10/05

namespace f4
{
    class arithMetic
    {

        static void Main(string[] args)
        {
            //主函数
        }

        class work
        {
            int[] numbers;
            string[] optionsArray = new string[] { "+", "-", "*", "/", "(", ")" };//运算符号和括号
            string[] fourOptions = new string[] { "+", "-", "*", "/" };//四则运算符
        }

        //运算符优先级
        static int privority(string str)
        {

            int pri = 0;
            switch (str)
            {
                case "+": pri = 0; break;
                case "-": pri = 0; break;
                case "*": pri = 1; break;
                case "/": pri = 1; break;
                case "(": pri = 2; break;
                case ")": pri = 2; break;
            }
            return pri;
        }

        //四则运算
        static int[] OptionsArithMetic(string firOps, string secOps, string ops)
        {
            int first= int.Parse(firOps);
            int second = int.Parse(secOps);
            int res = 0;
            switch (ops)
            {
                case "+": res = first + second; break;
                case "-": res = first - second; break;
                case "*": res = first * second; break;
                case "/": res = first / second; break;
            }
                return res;
        }

        //分割表达式,并入队列
        public Queue<string> SplitExpress(string express)
        {
            
        }

        //中序表达式转换为后序表达式
        public List<string> InorderToPostorder(Queue<string> q)
        {

        }

        //计算后序表达式
        public bool IsResult(List<string> PostorderExpress, out decimal result)
        {

        }

先写个博客证明一下自己的工作,逃:)

enmmmmmm,写了函数随机生成20道四则运算题目:

//随机生成20道运算题
        static void RandOut()
        {
            Random rd = new Random();
            int num1, num2, num3, num4;
            char[] fourOptions = new char[] { +, -, *, / };//四则运算符
            int i, j, charnum;
            for (i = 0; i < 20; i++)
            {
                num1 = rd.Next();
                num2 = rd.Next();
                num3 = rd.Next();
                num4 = rd.Next();
                charnum = rd.Next() % 4;
                for (j = 0; j < 3; j++)
                {
                    if (charnum == 0)
                    {
                        fourOptions[j] = +;
                    }
                    if (charnum == 1)
                    {
                        fourOptions[j] = -;
                    }
                    if (charnum == 2)
                    {
                        fourOptions[j] = *;
                    }
                    if (charnum == 3)
                    {
                        fourOptions[j] = /;
                    }
                    Console.WriteLine(num1 + fourOptions[j] + num2 + fourOptions[j] + num3 + fourOptions[j] + num4);
                }
            }
        }

下面是实现将遍历中序表达式转化为后序表达式:

//是否为数字,判断是否为整数字符串  
        static bool isNumber(string message)
        {
            //判断是否为整数字符串  
            //是的话则将其转换为数字并将其设为out类型的输出值、返回true, 否则为false  
            int result = -1;   //result 定义为out 用来输出值  
            try
            {
                result = Convert.ToInt32(message);
                return true;
            }
            catch
            {
                return false;
            }
        }

        //判断操作符优先级大小  
        static bool comparePriority(string op1, string op2)
        {
            return getPriorityValue(op1) > getPriorityValue(op2);
        }

        private static int getPriorityValue(string op1)
        {
            throw new NotImplementedException();
        }

        static Stack<string> changeExpression(List<string> beforeExps)
        {
            Stack<string> operand = new Stack<string>();//操作数  
            Stack<string> opertor = new Stack<string>();//操作符  
            //遍历中序表示  
            int length = beforeExps.Count;
            int len = opertor.Count;
            //判断是否为操作数    
            for (int i = 0; i < length; i++)
            {
                string c = beforeExps[i];
                if (isNumber(c))
                {
                    //操作数 存在操作数栈  
                    operand.Push(c);
                }
                else
                {
                    //为运算符    
                    //若运算符为"("直接存入到运算符栈中   
                    if (c == "(")
                    {
                        opertor.Push(c);
                    }
                    else if (c == ")")
                    {
                        //该运算符为右括号")",则输出运算符堆栈中的运算符到操作数堆栈,直到遇到左括号为止。 将"("出栈    
                        while (opertor.Peek() != "(")
                        {
                            string stringvalue = opertor.Pop();
                            operand.Push(stringvalue);
                        }
                        opertor.Pop();
                    }
                    else
                    { 
                        // 该运算符为非括号运算符:  
                        //考虑栈顶为空的情况   
                        if (len <=  0)
                        {
                            opertor.Push(c);
                            continue;
                        }
                        // (a) 若运算符堆栈栈顶的运算符为括号,则直接存入运算符堆栈。  
                        ////符合为左括号 直接存入运算符  
                        if (opertor.Peek() == "(")
                        {
                            opertor.Push(c);
                        }
                        else
                        {
                            //(b) 若比运算符堆栈栈顶的运算符优先级高或相等,则直接存入运算符堆栈。    
                            if (comparePriority(c, opertor.Peek()))
                            {
                                opertor.Push(c);
                            }
                            else
                            {
                                // (c) 若比运算符堆栈栈顶的运算符优先级低,则输出栈顶运算符到操作数堆栈,并将当前运算符压入运算符堆栈。  
                                string stringvalue = opertor.Pop();
                                operand.Push(stringvalue);
                                opertor.Push(c);
                            }

                        }
                    }
                }
            }
            //4、当表达式读取完成后运算符堆栈中尚有运算符时,则依序取出运算符到操作数堆栈,直到运算符堆栈为空。  
            while (len > 0)
            {
                string stringvalue = opertor.Pop();
                operand.Push(stringvalue);
            }
            //反转operand 获取正常的后缀表达式  
            Stack<string> resultSt = new Stack<string>();
            while (len > 0)
            {
                string stringvalue = operand.Pop();
                resultSt.Push(stringvalue);
            }
            return resultSt;
        }

 

以上是关于四则运算的主要内容,如果未能解决你的问题,请参考以下文章

如何在 python 中并行化以下代码片段?

20个简洁的 JS 代码片段

获取 badarith,[erlang,'+',[error,0],[],同时使用 Erlang 片段在 TSUNG 中执行算术运算

20个简洁的 JS 代码片段

四则运算

四则运算单元测试