#include<iostream>
#include<string>
#include<vector>
#include<stack>
using namespace std;
class Token{
public:
int kind;//0:符号 1:数字
char sym;//记录符号
float value;//记录数值
};
bool bigger(char c1,char c2){//运算符优先级比较
if(c2=='#'){return 1;}
if((c1=='+' || c1=='-') && (c2=='+' || c2=='-'))return 1;
if((c1=='*' || c1=='/') && (c2=='*' || c2=='/'))return 1;
if((c1=='+' || c1=='-') && (c2=='*' || c2=='/'))return 0;
if((c1=='*' || c1=='/') && (c2=='+' || c2=='-'))return 1;
}
typedef vector<Token> Token_List;//token序列
typedef stack<float> Num_Stack;//数字栈
typedef stack<char> Symbol_Stack;//符号栈
typedef stack<string> Postfix_Express;
void print(Token const& t){//输出一个token
cout<<t.kind<<" ";
if(t.kind==0){cout<<t.sym<<" -"<<endl;}
else{
if(t.kind==1){cout<<"- "<<t.value<<endl;}
}
}
void show(Token_List const& t){//输出token列表
for_each(t.begin(),t.end(),print);
}
float cal(float n1,float n2,char c){//计算 n1 c n2的值
switch(c){
case '+':cout<<n1<<c<<n2<<" = "<<n1+n2<<endl;return n1+n2;
case '-':cout<<n1<<c<<n2<<" = "<<n1-n2<<endl;return n1-n2;
case '*':cout<<n1<<c<<n2<<" = "<<n1*n2<<endl;return n1*n2;
case '/':cout<<n1<<c<<n2<<" = "<<n1/n2<<endl;return n1/n2;
}
}
int main(){
string s;
cin>>s;//输入字符串,以#号结束
//如 (1+3)*(2-4/1)#
//如 (-0.3)*(2+2)#
cout<<"输入格式如 (-0.3)*(2+3)# 的式子即可得出结果\n";
int pos=0;
while((pos=s.find('+',pos))!=string::npos){
if(!isdigit(s.at(pos-1))){
s.insert(pos,"0");pos+=1;
}
pos++;
}
pos=0;
while((pos=s.find('-',pos))!=string::npos){
if(!isdigit(s.at(pos-1))){s.insert(pos,"0");pos+=1;}
pos++;
}
Token_List token;
char const* str=s.c_str();
Token* t=new Token;
while(*str!='\0'){//扫描字符串得出token序列
if(*str=='#'){
cout<<0<<" "<<*str<<0<<endl;
t->kind=0;t->sym=*str;t->value=0;
str++;
}
if(*str=='(' || *str==')' || *str=='+' || *str=='-' || *str=='*' || *str=='/'){
cout<<0<<" "<<*str<<" "<<0<<endl;
t->kind=0;t->sym=*str;t->value=0;
str++;
}
else{
if((*str>='0' && *str<='9')){
cout<<1<<" a "<<atof(str)<<endl;
t->kind=1;t->sym='a';t->value=atof(str);
while((*str>='0' && *str<='9')||(*str)=='.')str++;
}
}
token.push_back(*t);
}
show(token);
Symbol_Stack ss;
Num_Stack ns;
float n1,n2,result;char c;
Token_List::iterator it;
for(it=token.begin();it!=token.end();it++){
if(it->kind==1){
ns.push(it->value);cout<<"ns压入"<<it->value<<endl;
}
else{
if(it->kind==0){
if(it->sym=='(' || ss.size()==0 || ss.top()=='('){ss.push(it->sym);cout<<"ss压入"<<it->sym<<endl;}
else{
if(it->sym==')'){
n2=ns.top();ns.pop();cout<<"ns弹出"<<n2<<endl;
n1=ns.top();ns.pop();cout<<"ns弹出"<<n1<<endl;
c=ss.top();ss.pop();ss.pop();cout<<"ss弹出"<<c<<endl;cout<<"ss弹出"<<'('<<endl;
result=cal(n1,n2,c);ns.push(result);cout<<"ns压入"<<result<<endl;
}
else{
if(bigger(ss.top(),it->sym)){
n2=ns.top();ns.pop();cout<<"ns弹出"<<n2<<endl;
n1=ns.top();ns.pop();cout<<"ns弹出"<<n1<<endl;
c=ss.top();ss.pop();cout<<"ss弹出"<<c<<endl;
result=cal(n1,n2,c);ns.push(result);cout<<"ns压入"<<result<<endl;
ss.push(it->sym); cout<<"ss压入"<<it->sym<<endl;
}
else{
n1=ns.top();ns.pop();cout<<"ns弹出"<<n1<<endl;
c=it->sym;
++it;
n2=it->value;
result=cal(n1,n2,c);ns.push(result);cout<<"ns压入"<<result<<endl;
}
}
}
}
}
}
if(ss.top()=='#'){cout<<"成功计算\n"<<ns.top()<<endl;}
else{
cout<<"错误\n";exit(1);
}
system("pause");
}
例如输入
2*(-9-6)*7#
得出结果
1 a 2
0 * 0
0 ( 0
1 a 0
0 - 0
1 a 9
0 - 0
1 a 6
0 ) 0
0 * 0
1 a 7
0 #0
1 - 2
0 * -
0 ( -
1 - 0
0 - -
1 - 9
0 - -
1 - 6
0 ) -
0 * -
1 - 7
0 # -
ns压入2
ss压入*
ss压入(
ns压入0
ss压入-
ns压入9
ns弹出9
ns弹出0
ss弹出-
0-9 = -9
ns压入-9
ss压入-
ns压入6
ns弹出6
ns弹出-9
ss弹出-
ss弹出(
-9-6 = -15
ns压入-15
ns弹出-15
ns弹出2
ss弹出*
2*-15 = -30
ns压入-30
ss压入*
ns压入7
ns弹出7
ns弹出-30
ss弹出*
-30*7 = -210
ns压入-210
ss压入#
成功计算
-210