四则运算
Posted 袁玥
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了四则运算相关的知识,希望对你有一定的参考价值。
算法:
一、 将中缀表达式转换成后缀表达式算法:
1、从左至右扫描一中缀表达式。
2、若读取的是操作数,则判断该操作数的类型,并将该操作数存入操作数堆栈
3、若读取的是运算符
(1) 该运算符为左括号"(",则直接存入运算符堆栈。
(2) 该运算符为右括号")",则输出运算符堆栈中的运算符到操作数堆栈,直到遇到左括号为止。
(3) 该运算符为非括号运算符:
(a) 若运算符堆栈栈顶的运算符为括号,则直接存入运算符堆栈。
(b) 若比运算符堆栈栈顶的运算符优先级高或相等,则直接存入运算符堆栈。
(c) 若比运算符堆栈栈顶的运算符优先级低,则输出栈顶运算符到操作数堆栈,并将当前运算符压入运算符堆栈。
4、当表达式读取完成后运算符堆栈中尚有运算符时,则依序取出运算符到操作数堆栈,直到运算符堆栈为空。
二、逆波兰表达式求值算法:
对后缀表达式求值比直接对中缀表达式求值简单。在后缀表达式中,不需要括号,而且操作符的优先级也不再起作用了。可以用如下算法对后缀表达式求值:
- 初始化一个空堆栈
- 从左到右读入后缀表达式
- 如果字符是一个操作数,把它压入堆栈。
- 如果字符是个操作符,弹出两个操作数,执行恰当操作,然后把结果压入堆栈。如果您不能够弹出两个操作数,后缀表达式的语法就不正确。
- 到后缀表达式末尾,从堆栈中弹出结果。若后缀表达式格式正确,那么堆栈应该为空。
功能一的实现:
参考了一个博客:计划写出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; }
以上是关于四则运算的主要内容,如果未能解决你的问题,请参考以下文章
获取 badarith,[erlang,'+',[error,0],[],同时使用 Erlang 片段在 TSUNG 中执行算术运算