字符串-四则运算
题目大意:
有字符串表示的一个四则运算表达式,要求计算出该表达式的正确数值。四则运算即:加减乘除"+-*/",另外该表达式中的数字只能是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; }
作者:ballwql
本文为作者原创,版权所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。