题目大意:
给出一串只涉及整形加减乘除四则运算式子,求出式子的结果。
思路分析:
运用两个栈,一个用来存数字,一个用来存加减乘除运算符,从头到尾扫描字符串,把数字存入数字栈,再看运算符,如果是第一个运算符,那么就直接压入栈,否则,把当前运算符和运算符栈栈底元素比较,如果当前运算符的优先级高于栈底元素,那么就把数字栈取出一个数字,在与它后一个元素进行运算,否则取出两个数字进行运算。。。
代码实现:
#include<cstdio>
#include<cstring>
#include<stack>
#include<cctype>
#include<cmath>
#include<iostream>
using namespace std;
const int N=1000005;
long long num[N];
int tmp[N];
char oper[N],tmp2[N],str[N];
int Precedence(char op1,char op2){
if(op1=='+'||op1=='-'){
if(op2=='*'||op2=='/') return 1;
else if(op2=='+'||op2=='-') return 0;
}else return 0;
}
long long Calculate(char op,long long a,long long b){
if(op=='+') return a+b;
else if(op=='-') return a-b;
else if(op=='*') return a*b;
else return a/b;
}
double Change(int cnt){
int res=0,t=1;
for(int i=cnt-1;i>=0;--i){
res+=tmp[i]*t;
t*=10;
}
return res;
}
int main(){
int n;
scanf("%d",&n);
while(n--){
long long sum=0;
stack<long long> s1;
stack<char> s2;
int c1=0,c2=0,ans,l,cnt=0;
long long a,b,t,res;
char op;
scanf("%s",str);
l=strlen(str);
for(int i=0;i<l;++i){
if(isdigit(str[i])) tmp[cnt++]=str[i]-'0';
else{
num[c1++]=(long long)Change(cnt);
oper[c2++]=str[i];
cnt=0;
}
}
num[c1++]=(long long)Change(cnt);
for(int i=0,j=0;i<c1,j<c2;++i,++j){
s1.push(num[i]);
if(s2.empty()) s2.push(oper[j]);
else{
ans=Precedence(s2.top(),oper[j]);
if(ans){
t=s1.top();
s1.pop();
res=Calculate(oper[j],t,num[i+1]);
num[i+1]=res;
}else{
a=s1.top(),s1.pop();
b=s1.top(),s1.pop();
op=s2.top(),s2.pop();
res=Calculate(op,b,a);
s1.push(res);
s2.push(oper[j]);
}
}
}
s1.push(num[c1-1]);
c1=c2=0;
a=s1.top(),s1.pop();
b=s1.top(),s1.pop();
op=s2.top(),s2.pop();
res=Calculate(op,b,a);
printf("%lld\n",res);
}
}
方法二:直接在进行运算符入栈过程中,如果栈顶的运算符优先级高,就出栈一直到栈顶运算符优先级低于当前运算符的优先级。
#include<cstdio>
#include<cstring>
#include<stack>
#include<cctype>
#include<cmath>
#include<iostream>
using namespace std;
const int N=1000005;
long long num[N];
int tmp[N];
char oper[N],tmp2[N],str[N];
int Precedence(char op1,char op2){
if(op1=='+'||op1=='-'){
if(op2=='*'||op2=='/') return 1;
else if(op2=='+'||op2=='-') return 0;
}else return 0;
}
long long Calculate(char op,long long a,long long b){
if(op=='+') return a+b;
else if(op=='-') return a-b;
else if(op=='*') return a*b;
else return a/b;
}
double Change(int cnt){
int res=0,t=1;
for(int i=cnt-1;i>=0;--i){
res+=tmp[i]*t;
t*=10;
}
return res;
}
int main(){
int n;
scanf("%d",&n);
while(n--){
long long sum=0;
stack<long long> s1;
stack<char> s2;
int c1=0,c2=0,ans,l,cnt=0;
long long a,b,t,res;
char op;
scanf("%s",str);
l=strlen(str);
for(int i=0;i<l;++i){
if(isdigit(str[i])) tmp[cnt++]=str[i]-'0';
else{
num[c1++]=(long long)Change(cnt);
oper[c2++]=str[i];
cnt=0;
}
}
num[c1++]=(long long)Change(cnt);
for(int i=0,j=0;j<c2;++i,++j){
s1.push(num[i]);
if(s2.empty()) s2.push(oper[j]);
else{
ans=Precedence(s2.top(),oper[j]);
if(ans) s2.push(oper[j]);
else{
while(!s2.empty()&&!Precedence(s2.top(),oper[j])){
a=s1.top(),s1.pop();
b=s1.top(),s1.pop();
op=s2.top(),s2.pop();
res=Calculate(op,b,a);
s1.push(res);
}
s2.push(oper[j]);
}
}
}
s1.push(num[c1-1]);
while(!s2.empty()){
a=s1.top(),s1.pop();
b=s1.top(),s1.pop();
op=s2.top(),s2.pop();
res=Calculate(op,b,a);
s1.push(res);
}
printf("%lld\n",s1.top());
}
}