由于运算符有优先级,因此计算时要先计算优先级高的,并且,运算符相同的话,前一个的优先级要高,如1+2+3,先计算1+2,再计算3+3。为了符合运算规则,计算时从左到右扫描算式,先将扫描到的数字和运算符保存起来,直到遇到一个运算符的优先级比后一个高,才对优先级高的运算符进行运算。那么,用什么保存扫描到的信息呢?栈。
开两个数组,一个作为运算数栈,只存数字,一个作为算术符栈,只存算术符。
扫描算式过程中,主要有两个操作:
1,遇到数字则将其压入数字栈;
2,遇到运算符,则将其与算术符栈的栈顶元素比较,若栈顶运算符优先级高,说明它比要压入的运算符先计算,于是将其弹出,并从数字栈中弹出两个数字, 然后根据弹出 的运算符进行计算,将结果再压入栈。接着,将原本要压入栈的运算符继续跟此时的算术符栈的新栈顶元素比较,重复这个操作直到栈空或栈顶元素优先级比要压入的运 算符低。
扫描完算式后,检查运算符栈是否为空,若为空的话,说明计算完毕,否则说明还有运算符没有参与计算,将其弹出进行计算。
由于表达式一定合法,因此,最后数字栈的栈顶元素就是计算结果。
代码如下:
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <cmath>
using namespace std;
const int N=1000;
int s1[N],n;
char s2[N],s[N];
int compare(char op) // 优先级设置
{
int t;
switch(op)
{
case '+':
case '-':
t=1; break;
case '*':
case '/':
t=2; break;
default:
t=0;
}
return t;
}
int calculate(int a,char op,int b) // 两个数的计算
{
int t;
switch(op)
{
case '+':
t=a+b; break;
case '-':
t=a-b; break;
case '*':
t=a*b; break;
case '/':
t=a/b; break;
}
return t;
}
int main()
{
//char s[N];
freopen("D:\\in.txt","r",stdin);
freopen("D:\\out.txt","w",stdout);
while(cin>>s)
{
int i,j=0,k=0;
int n=strlen(s);
s2[k++]='#';
for (i=0;i<n;i++){
if (isdigit(s[i])) { s1[j++]=s[i]-'0'; }
else {
while (compare(s2[k-1])>=compare(s[i])){ //cout<<compare(s[i])<<endl;
int a=s1[--j];
int b=s1[--j];
s1[j++]=calculate(b,s2[k-1],a); //cout<<s1[j-1]<<" "<<k<<endl;
k--;
if (k-1==0) break;
}
s2[k++]=s[i];
}
}
while(k>0){
int a=s1[--j];
int b=s1[--j];
s1[j++]=calculate(b,s2[k-1],a);
k--;
}
printf("%d\n",s1[j-1]);
}
}
/*
1-2*3*4-9
*/