1356:计算(calc)
时间限制: 1000 ms 内存限制: 65536 KB
提交数:16144 通过数: 7008
【题目描述】
小明在你的帮助下,破密了Ferrari设的密码门,正要往前走,突然又出现了一个密码门,门上有一个算式,其中只有“(”,“)”,“0-9”,“+”,“-”,“*”,“/”,“^”,求出的值就是密码。小明数学学得不好,还需你帮他的忙。(“/”用整数除法)
【输入】
共1行,为一个算式。
【输出】
共1行,就是密码。
【输入样例】
1+(3+2)*(7^2+6*9)/(2)
【输出样例】
258
思路:定义2个栈,数据栈 与符号栈,定义一个符号优先级函数,判断每个字符的情况,要么是数字或者其它,其它(先把数字进栈),然后判断 是左括号(直接进栈),如果是右括号 退到最近的一个左括号,如果是其它符号,比较当前符号与优先级与栈顶的优先级。循环结束之后,需要清空栈,每次运算的过程都是数字栈 退2 进1
#include<bits/stdc++.h> using namespace std; typedef long long ll; stack<ll> st1; stack<char> st2; int level(char ch) { if(ch=='+'||ch=='-') return 1; if(ch=='*'||ch=='/') return 2; if(ch=='^') return 3; return 0; } void calc() { // st1,退2个数字,第2个数字为a // st2 退一个符号,,根据符号计算结果,讲结果干到st1 ll a,b; b=st1.top();st1.pop(); a=st1.top();st1.pop(); char ch; ch=st2.top();st2.pop(); ll c;//结果 switch(ch) { case '+': c=a+b;break; case '-': c=a-b;break; case '*': c=a*b;break; case '/': c=a/b;break; case '^': c=pow(a,b);break; } // 结果c,入st1 st1.push(c); } int main() { string s; cin>>s; int i; int f=0;//数字标记 long long sum=0;// 初始化0 for(i=0;i<s.size();i++) { if(s[i]>='0'&&s[i]<='9') { sum=sum*10+s[i]-'0'; f=1; } else { // 如果前面是数字,这这个sum进st1 if(f==1) { st1.push(sum); f=0;// 非数字 sum=0;//初始0 } // 有可能是 左括号,右括号,运算符号 if(s[i]=='(') { st2.push(s[i]); continue; } else if(s[i]==')')// 退到最近的左括号 { while(st2.size()>0&&st2.top()!='(') { calc(); } st2.pop();// 退掉这个匹配的左括号 continue; } else // 运算符号,优先级 栈顶》= 当前 都需要先计算 { while(st2.size()>0&&level(st2.top())>=level(s[i])) { calc(); } st2.push(s[i]);// 这个符号,入栈st2 } } } // 最后一个以数字结尾,sum 入队列 if(f==1) { st1.push(sum); } // st2 里面的符号都是并列 ,不停的运算清空 while(st2.size()>0) { calc(); } cout<<st1.top(); return 0; }