中缀表达式与前缀表达式

一、目标:

1.输入中缀表达式,转化为前缀表达式,输出前缀表达式字符串

2.输入前缀表达式,输出计算结果

3.输入中缀表达式,通过转化为前缀表达式输出计算结果

 

二、与 中缀->后缀的不同:

  1.中缀->后缀从左往右扫描中缀表达式字符串;扫描到操作数直接输出,而操作符是在弹栈时输出,即得到后缀表达式字符串

     中缀->前缀从右往左扫描中缀表达式字符串;扫描到操作数时直接压入“输出栈”,而操作符是在弹出操作符栈时压入“输出栈”,最后对输出栈进行弹栈、输出,即得到前缀表达式字符串

  2.运算符优先级:// isp 为栈顶操作符优先级 ;icp 为当前扫描操作符优先级

       中缀->后缀isp[ ' ( ' ]=0 ; icp[ ' ( ' ]=5 ; 

             isp[ ' ) ' ]=5 ; icp[ ' ) ' ]=0 ;

             isp[ ' + ' ]=2 ; icp[ ' + ' ]=1 ;

             isp[ ' - ' ]=2 ; icp[ ' - ' ]=1 ;

             isp[ ' * ' ]=4 ; icp[ ' * ' ]=3 ;

             isp[ ' / ' ]=4 ; icp[ ' / ' ]=3 ;

       中缀->前缀:   isp[ ' ( ' ]=5 ; icp[ ' ( ' ]=0 ;

                  isp[ ' ) ' ]=0 ; icp[ ' ) ' ]=5 ;

             isp[ ' + ' ]=1 ; icp[ ' + ' ]=2 ;

             isp[ ' - ' ]=1 ; icp[ ' - ' ]=2 ;

             isp[ ' * ' ]=3 ; icp[ ' * ' ]=4 ;

             isp[ ' / ' ]=3 ; icp[ ' / ' ]=4 ;

  3.前缀表达式相当于从右往左扫描中缀表达式所得到的后缀表达式的逆序

 

三、C++实现

1.输入中缀表达式,转化为前缀表达式,输出前缀表达式字符串

void convertToPre(const string &s){
    int len=s.length();
    stack<char>output;
    stack<char>operators;
    for(int i=len-1;i>=0;--i){
        if(s[i]>='0'&&s[i]<='9'){
            output.push(s[i]);
        }else if(operators.empty()){    
            operators.push(s[i]);
        }else{
            while(!operators.empty()&&isp[operators.top()]>icp[s[i]]){
                output.push(operators.top());
                operators.pop();
            }
            if(!operators.empty()&&isp[operators.top()]==icp[s[i]]){
                operators.pop();
            }else{
                operators.push(s[i]);
            }
        }
    }
    while(!operators.empty()){
        output.push(operators.top());
        operators.pop();
    }
    while(!output.empty()){
        cout<<output.top();
        output.pop();
    }
}

 

2.输入前缀表达式,输出计算结果

double calculatePre(const string &s){
    int len=s.length();
    stack<double>operands;
    for(int i=len-1;i>=0;--i){
        if(s[i]>='0'&&s[i]<='9'){
            operands.push(s[i]-'0');
        }else{
            int a=operands.top();
            operands.pop();
            int b=operands.top();
            operands.pop();
            operands.push(calculate(a,b,s[i])); 
        }
    }
    return operands.top();
}

 

3.输入中缀表达式,通过转化为前缀表达式输出计算结果

//其实前缀表达式在栈中的次序就是一个从右往左读中缀表达式得到的后缀表达式
//只是出栈(逆转了一下次序)后,就变成了所谓的前缀表达式 
double calculateInByPre(const string &s){
    int len=s.length();
    stack<char>operators;
    stack<double>operands;
    for(int i=len-1;i>=0;--i){
        if(s[i]>='0'&&s[i]<='9'){
            operands.push(s[i]-'0');
        }else if(operators.empty()){
            operators.push(s[i]);
        }else{
            while(!operators.empty()&&isp[operators.top()]>icp[s[i]]){
                int a=operands.top();
                operands.pop();
                int b=operands.top();
                operands.pop();
                operands.push(calculate(a,b,operators.top()));
                operators.pop();
            }
            if(!operators.empty()&&isp[operators.top()]==icp[s[i]]){
                operators.pop();
            } else{
                operators.push(s[i]);
            }
        }
    }
    while(!operators.empty()){
        int a=operands.top();
        operands.pop();
        int b=operands.top();
        operands.pop();
        operands.push(calculate(a,b,operators.top()));
        operators.pop();
    }
    return operands.top();
}

 

测试:

#include<iostream>
#include<map>
#include<stack>
#include<string>
using namespace std;

map<char,int>isp;//栈顶的字符的优先级 
map<char,int>icp;//读到的字符的优先级 
//此处的优先级是用来判断当前读到的这个字符和栈顶字符的优先级的
//并不用管还未读到的字符以及非栈顶的字符 

void buildPriority(){
    isp['+']=1;icp['+']=2;
    isp['-']=1,icp['-']=2;
    isp['*']=3;icp['*']=4;
    isp['/']=3;icp['/']=4;
    isp['(']=5;icp['(']=0;
    isp[')']=0;icp[')']=5;
}

double calculate(double a,double b,char oprt){
    switch(oprt){
        case'+':
            return a+b;
            break;
        case'-':
            return a-b;
            break;
        case'*':
            return a*b;
            break;
        case'/':
            return a/b;
            break;
        default:
            break;
    }
    return 0;
}

int main(){
    string inExpr,preExpr;
    
    buildPriority();
    
    cout<<"input the infix expression : "<<endl;
    cin>>inExpr;
    cout<<"\nconvert to prefix expression : "<<endl;
    convertToPre(inExpr);
    cout<<"\ncalculate infix by prefix , result = "<<calculateInByPre(inExpr);
    
    cout<<"\n\ninput the prefix expression : "<<endl;
    cin>>preExpr;
    cout<<"\nthe result = "<<calculatePre(preExpr);
}

 

posted @ 2021-04-02 16:09  NoerForest  阅读(412)  评论(0)    收藏  举报