题目:给出一个表达式,如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;
}