题目描述
算数四则运算的规则是1)先乘除,后加减;2)从左算到右;3)先括号内,后括号外。
由此,算式4+2*3-10/5的计算顺序为4+2*3-10/5=4+6-10/5=4+6-2=8。
给定一个以“#”作为结束符的算式,求出算式的结果。
输入
以“#”结尾的表达式,运算数为正整数。每个表达式占一行。
输出
输出表达式运算的结果。
样例输入
4+2*3-10/5# 3*(7-2)# 2*3/2#
样例输出
8 15 3
#include<iostream>
#include<stack>
#include<cstring>
#include<string>
using namespace std;
string s;
stack<int> ns;
stack<int> os;
int idx;
//针对有小括号的表达式,策略是扩充符号优先级矩阵 ,左括号优先级最高,右括号优先级最低
//括号内的先运算,右括号不入栈而是运算开始的标志,遇到左括号则括号内运算结束
int map[7][7]={
1,0,0,0,0,0,0,
1,0,0,0,0,1,1,
1,0,0,0,0,1,1,
1,1,1,0,0,1,1,
1,1,1,0,0,1,1,
1,1,1,1,1,1,1,
1,0,0,0,0,0,0
};
void getnext(int &flag,int &num,int &op)
{
flag=0;
num=0;
int temp=0;
int c=1;
if(idx==0)
{
os.push(0);
}
if('0'<=s[idx]&&s[idx]<='9')
{
flag=0;
int last=0;
for(int i=idx;i<s.length();i++)
{
if('0'<=s[i]&&s[i]<='9')
{
last++;
}else
{
break;
}
}
//这样读出来的数字是反的 734读成437
for(int i=idx+last-1;i>=idx;i--)
{
if('0'<=s[i]&&s[i]<='9')
{
//cout<<"s[i]:"<<s[i]<<endl;
num+=c*(s[i]-'0');
c*=10;
}else
{
break;
}
}
idx+=last;
}
else
{
if(s[idx]=='+')
{
flag=1;
num=0;
op=1;
}
if(s[idx]=='-')
{
flag=1;
num=-1;
op=2;
}
if(s[idx]=='*')
{
flag=1;
op=3;
}
if(s[idx]=='/')
{
flag=1;
op=4;
}
if(s[idx]=='(')
{
flag=1;
op=5;
}
if(s[idx]==')')
{
flag=1;
op=6;
}
if(s[idx]=='#')
{
flag=1;
op=0;
return;
}
idx++;
}
/*
if(idx-1==s.length())
{
flag=1;
op=0;
return;
}
*/
}
int main()
{
while(cin>>s)
{
idx=0;
while(!ns.empty())
{
ns.pop();
}
while(!os.empty())
{
os.pop();
}
int f,n,o;
while(idx<=s.length())
{
getnext(f,n,o);
//printf("标志:%d 数值:%d 符号:%d\n",f,n,o);
if(f==0)
{
ns.push(n);
//printf("数值栈中压入数字 %d\n",n);
}
else
{
if(!os.empty())
{
//printf("符号栈非空 %d %d\n",o,os.top());
if(map[o][os.top()]==1)
{
//printf("符号栈中压入运算符 %d\n",o);
os.push(o);
}
else
{
// printf("当前运算符小于栈顶运算符 %d\n",o);
//一直弹到大于栈顶符号优先级
while(map[o][os.top()]==0)
{
int top=os.top();
if(top==5)
{
os.pop();//这注意!
//printf("弹出左括号\n");
//弹到左括号了,直接退出
break;
}
os.pop();//这注意!
int n1=ns.top();
ns.pop();
int n2=ns.top();
ns.pop();
if(top==1)
{
//printf("取两个数字运算 %d %d\n",n1,n2);
ns.push(n1+n2);
}
if(top==2)
{
//printf("取两个数字运算 %d %d\n",n1,n2);
ns.push(n2-n1);
}
if(top==3)
{
//printf("取两个数字运算 %d %d\n",n1,n2);
ns.push(n1*n2);
}
if(top==4)
{
//printf("取两个数字运算 %d %d\n",n1,n2);
ns.push(n2/n1);
}
}
//才压入该运算符,这里不压入右括号了
if(o!=6)
os.push(o);
//当符号栈中只有两个O,数值栈中只有最后一个计算结果的时候,运算结束
if(os.top()==0&&os.size()==2&&ns.size()==1)
{//计算结束
break;
}
}
}
}
}
// printf("运算结果 %d\n",ns.top());
printf("%d\n",ns.top());
}
}