问题描述
小 V 发明了一个神奇的整数计算器:
给定一个合法的表达式,这个计算器能求出这个表达式的最终答案。
表达式可能包含:
+:运算符,整数加法。如 1+1=2
-:运算符,整数减法。如 1-1=0
*:运算符,整数乘法。如 1*1=1
/:运算符,整数除法。如 3/2=1
(:左括号
):右括号
操作数:保证为非负整数,且操作数没有正号(如不会出现+1 等)
现在,给定一个表达式,小 V 在用这个计算器计算前想先知道最终答案是多少,你能
帮帮他吗?
★数据输入
一个合法的表达式,表达式长度不超过 1000。
★数据输出
表达式的最终结果。
★Notice
题目保证:输入的操作数,计算的中间值,计算的最终结果都在 int 范围内
★样例
1+1 2
1+2/3 1
(1+2)*3 9
解题思路
solve1
建立两个栈:数字栈、符号栈
按顺序遍历算式
遇到数字注意按多位数读取,压入数字栈
若符号栈为空或为 ' ( ' ,压入符号栈
遇到 + - / *,向前计算优先级大于等于本符号优先级的,算到 ' ( '停止。将本符号压入符号栈
优先级 / * 最高,+ - 次之
故 + - 前面的 + - * / 都要算, * / 前面的* / 要算, + -不算,遇到 + - 停止
遇到 ' ) ',向前算到 ' ( '
最后数字栈栈顶元素即为解
solve 2
将原表达式转换为后续表达式。
为能正确读取后续表达式,可在所有数字、符号间加上空格。
此时,表达式将比原表达式长,原来长度1000数组不够用,要开大一点
最后用后续表达式计算结果
附:中缀表达式转后缀表达式的方法
1.遇到操作数:直接输出(添加到后缀表达式中)
2.栈为空时,遇到运算符,直接入栈
3.遇到左括号:将其入栈
4.遇到右括号:执行出栈操作,并将出栈的元素输出,直到弹出栈的是左括号,左括号不输出。
5.遇到其他运算符:加减乘除:弹出所有优先级大于或者等于该运算符的栈顶元素,然后将该运算符入栈
6.最终将栈中的元素依次出栈,输出。
code
1 #include <stdio.h> 2 #include <iostream> 3 using namespace std; 4 #include <stack> 5 #include <string.h> 6 7 inline bool isNum(char c) 8 { 9 return c>='0' && c<='9'; 10 } 11 12 inline int toInt(char c) 13 { 14 return c-'0'; 15 } 16 17 int calc(int nl,int nr,char s) 18 { 19 if(s=='+') return nl+nr; 20 else if(s=='-') return nl-nr; 21 else if(s=='*') return nl*nr; 22 else if(s=='/') return nl/nr; 23 printf("errror"); 24 return 0; 25 } 26 27 int main() 28 { 29 int i,j,k; 30 char str[1024]={0}; 31 int len; 32 scanf("%s",str); 33 len = strlen(str); 34 35 stack<int> num; 36 stack<int> signal; 37 38 for(i=0;i<len;i++) 39 { 40 if(isNum(str[i])) 41 { 42 int n = toInt(str[i]); 43 for (j = i + 1; j < len && isNum(str[j]); j++) 44 n = n * 10 + toInt(str[j]); 45 num.push(n); 46 i = j - 1; 47 } 48 else // is signal 49 { 50 char thissign = str[i]; 51 if(thissign=='(' || signal.empty()) 52 { 53 signal.push(thissign); 54 } 55 else if(thissign=='+' || thissign=='-') 56 { 57 while(!signal.empty() && signal.top()!='(') 58 { 59 int nr = num.top(); 60 num.pop(); 61 int nl = num.top(); 62 num.pop(); 63 num.push(calc(nl,nr,signal.top())); 64 signal.pop(); 65 } 66 signal.push(thissign); 67 } 68 else if(thissign=='*' || thissign=='/') 69 { 70 while(!signal.empty() && ( signal.top()=='*' || signal.top()=='/') ) 71 { 72 int nr = num.top(); 73 num.pop(); 74 int nl = num.top(); 75 num.pop(); 76 num.push(calc(nl,nr,signal.top())); 77 signal.pop(); 78 } 79 signal.push(thissign); 80 } 81 else if(thissign==')') 82 { 83 while(!signal.empty() && signal.top()!='(') 84 { 85 int nr = num.top(); 86 num.pop(); 87 int nl = num.top(); 88 num.pop(); 89 num.push(calc(nl,nr,signal.top())); 90 signal.pop(); 91 } 92 signal.pop(); 93 } 94 } 95 } 96 while(!signal.empty()) 97 { 98 int nr = num.top(); 99 num.pop(); 100 int nl = num.top(); 101 num.pop(); 102 num.push(calc(nl,nr,signal.top())); 103 signal.pop(); 104 } 105 printf("%d ",num.top()); 106 return 0; 107 } 108