题目大意:
有字符串表示的一个四则运算表达式,要求计算出该表达式的正确数值。四则运算即:加减乘除"+-*/",另外该表达式中的数字只能是1位(数值范围0~9)。另若有不能整除的情况,按向下取整处理,eg: 8/3得出值为2。若有字符串"8+7*2-9/3",计算出其值为19。
题目来源:
2012年华为上机的一个题目
题目思路:
建立栈分别存储操作符和操作数,比较操作符的优先级,并以此决定操作数是否进行出栈运算还是直接入栈。只要对给定字符串,画出出入栈的顺序,整个题基本没问题,只是过程比较繁琐。我在题目用到是C++的Stack容器,当然自己构造一个栈结构也可以。
源码:
#include <iostream>
#include <stack>
using namespace std;
int cmp(const char c1,const char c2) //判断优先级
{
if(c1==c2) //相同操作符,及同级操作符
return 0;
if((c1=='*'||c1=='/')&&(c2=='*'||c2=='/'))//同级
return 0;
if((c1=='*'||c1=='/')&&(c2=='+'||c2=='-'))//
return 1;
if((c1=='+'||c1=='-')&&(c2=='*'||c2=='/'))
return -1;
}
int compute(const char* pstr) //计算结果
{
stack<int> copnd; //存储操作数
stack<char> copter; //存储操作符:+,-,*,/
char cnum[512]; //存储提取的操作数
int i=0;
int len=strlen(pstr);
int t1=0,t2=0,t3=0;//t1,t2:存储先后出栈的两操作数; t3:存储计算结果
for(i=0;i<len;++i)
{
if(pstr[i]>='0'&&pstr[i]<='9') //提取操作数,注意操作数超过10时如何处理
{
int k=0,tn=0;
while(isdigit(pstr[i]))
cnum[k++]=pstr[i++];
cnum[k]='\0';
tn=atoi(cnum);
memset(cnum,0,sizeof(cnum));
copnd.push(tn);
cout<<"opnd: push("<<tn<<")"<<endl;
i=i-1; //提取一个操作数完后,i已经指向下一位,需要重新调整,画图可以更好理解
}
else if(pstr[i]=='+'||pstr[i]=='-'||pstr[i]=='*'||pstr[i]=='/')
{
if(copter.empty()) //若栈为空,则直接将操作符入栈
{
copter.push(pstr[i]);//
cout<<"opter: push("<<pstr[i]<<")"<<endl;
}
else
{
switch(cmp(copter.top(),pstr[i]))
{
case 0: case 1: //同优先级操作符操作:先将操作数栈最顶层的两个元素出栈并根据操作符计算结果,然后将结果入操作数栈
t1=copnd.top();
cout<<"opnd: pop("<<t1<<")"<<endl;
copnd.pop();
t2=copnd.top();
copnd.pop();
cout<<"opnd: pop("<<t2<<")"<<endl;
switch(copter.top())
{
case '+':
t3=t2+t1;
copnd.push(t3);
cout<<"opnd: push("<<t3<<")"<<endl;
break;
case '-':
t3=t2-t1;
copnd.push(t3);
cout<<"opnd: push("<<t3<<")"<<endl;
break;
case '*':
t3=t2*t1;
copnd.push(t3);
cout<<"opnd: push("<<t3<<")"<<endl;
break;
case '/':
if(t1==0) //零除情况要考虑
return -1;//zero-divide
t3=(int)(t2/t1);
copnd.push(t3);
cout<<"opnd: push("<<t3<<")"<<endl;
break;
default:break;
}
copter.pop(); //同级操作符出栈
copter.push(pstr[i]); //同级操作符入栈
break;
case -1:
copter.push(pstr[i]); //栈内操作符优先级小于所提取的操作符,则直接将提取的操作符入栈
break;
default:break;
}
}
}
}
while(!copter.empty()) //当上述循环遍历至结尾时,至少最后的2个操作数未进行计算(至多3个操作数),可以画栈图理解
{
t1=copnd.top();
copnd.pop();
t2=copnd.top();
copnd.pop();
switch(copter.top())
{
case '+':
t3=t2+t1;
copnd.push(t3);
break;
case '-':
t3=t2-t1;
copnd.push(t3);
break;
case '*':
t3=t2*t1;
copnd.push(t3);
break;
case '/':
if(t1==0)
return -1;//zero-divide
t3=(int)(t2/t1);
copnd.push(t3);
break;
default:break;
}
copter.pop();
}
return t3;
}
int main()
{
cout<<compute("42+4*2-82-5/2")<<endl;
return 0;
}