计算器程序,支持+-*/和(),以#号结尾,有词法分析,和运算,没有语法分析是否正确,但是只要输入正确就能运行

#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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值