华为编程大赛——求表达式的值
题目:给出一个表达式,如1*2+8*9-(3+1+5),计算表达式的结果。
思路:考查关于逆波兰式的用法,具体可看《大话数据结构》。
代码如下:
/* 1.中缀转后缀 2.后缀进行求值 */ #include<iostream> #include <stack> #include <map> #include <string> #include <cctype> #include<vector> #define MAX 1000 using namespace std; //函数原型 //————1——————获取后缀表达式 //1.遇到左括号压栈,遇到右括号出栈至左括号 //2.当前操作符比栈顶操作符优先级大,则压栈;否则出栈直至遇到小的或栈为空。 //3.遇到数字直接存到vector容器中 void GetRPN(vector<char>& cvec, char *input){ cvec.clear(); //定义 int length=strlen(input);//表达式的长度 stack<char> s1;//存储运算符 s1.push('#');//'#'作为结束标志。 char top_char; //利用map实现优先级 map<char,int> operation; operation['#']=0; operation['(']=1; operation['+']=2; operation['-']=2; operation['*']=3; operation['/']=3; //进行操作 for(int i=0;i<length;i++){ top_char=s1.top(); if(isdigit(input[i])){ //如果为操作数,直接进vector cvec.push_back(input[i]); }else if(input[i]=='('){ //如果为'(',直接进s1 s1.push('('); }else if(input[i]==')'){ //把成对操作数的运算符压入vector while(top_char!='(' ){ cvec.push_back(top_char); s1.pop(); top_char=s1.top(); } s1.pop();//去除与当前')'成对的'(' }else if(operation[input[i]]>operation[top_char]){ //如果操作符的优先级大于当前栈顶,则进s1 s1.push(input[i]); }else if(operation[input[i]]<=operation[top_char]){ //如果操作符的优先级小于等于当前栈顶 while(operation[input[i]]<=operation[top_char] && input[i]!='\0'){ cvec.push_back(top_char);//将s1的栈顶入vector s1.pop(); top_char=s1.top(); } s1.push(input[i]);//当前操作符进栈 } } top_char=s1.top(); while(top_char!='#'){ cvec.push_back(top_char); s1.pop(); top_char=s1.top(); } } //——————2——————计算子表达式的 a+b的值 double Cal(double lhs, double rhs, char oper ){ double ret=0.0; switch(oper){ case '+': ret=lhs+rhs; break; case '-': ret=lhs-rhs; break; case '*': ret=lhs*rhs; break; case '/': if(0==rhs){//需要判断分母是否为0; cout<<"error rhs!\n"; exit(1); }else{ ret=lhs/rhs; break; } default: break; } return ret; } //——————3————————用户使用的计算函数 double Trans( char* input){ stack<double> s; double lhs,rhs; double calRes=0.0; vector<char>cvec;//声明一个vector用于存储后缀表达式 GetRPN(cvec,input);//调用函数获得后缀表达式 vector<char>::const_iterator iter=cvec.begin(); for(; iter!=cvec.end(); ++iter) //打印 cout<<*iter; for(iter=cvec.begin(); iter!=cvec.end(); ++iter){ if( isdigit(*iter) ){ s.push(*iter-'0'); }else{ rhs=s.top(); s.pop(); lhs=s.top(); s.pop(); calRes=Cal(lhs,rhs,*iter); s.push(calRes); } } return calRes; } int main(){ char test[]="1*2+8*9-(3+1+5)"; double res=Trans(test); cout<<endl<<"result is: "<<res<<endl; putchar(10); return 0; }