中缀表达式转换为后缀表达式(栈的使用)

栈的基本结构

这是一种先进后出的数据结构。可以类比到生活中的羽毛球筒,最先放进去的羽毛球最后取出来。

常用函数

stack<Typename> 定义栈名。
stack<int>S;

S.push(x); // 往栈中压入x元素
S.pop(); //弹栈
S.empty() //判栈空,如果为空,则返回值为1,否则,为0;
S.top();

stack<int>S;                //定义一个int类型的栈
    for(int i = 1;i <= 10;i ++) // 依次往栈里压入元素
        S.push(i);
    while(!S.empty()){           //判栈空
        cout << S.top() << end;  //取栈顶并输出
        S.pop();                 //将栈顶弹出
    }

中缀表达式转换为后缀表达式

例题

算术表达式有前缀表示法、中缀表示法和后缀表示法等形式。日常使用的算术表达式是采用中缀表示法,即二元运算符位于两个运算数中间。请设计程序将中缀表达式转换为后缀表达式。

思路

采用两个栈来存放元素,这里的元素定义为string类型,因为既有字符也有数字(如果用int类型来存放就会有局限性,用阿斯科码来表示,比如说如果出现小数);
同时还要处理运算符之间的关系。
这是关于无括号的运算符的运算关系

代码(小数、数字前带符号,带括号的中缀转后缀)

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

string str;
int judge[7][7]{             //用一个二维数组来存放各个元素个关系
    {0,0,-1,-1,1,-1},        //小于0,表示第一个下标对应的符号比第二个
    {0,0,-1,-1,1,-1},        //符号的优先级高
    {1,1,0,0,1,-1},
    {1,1,0,0,1,-1},
    {-1,-1,-1,-1,0,-1},
    {1,1,1,1,1,0}
};                // 一共有7维,因为还有‘(’的关系,‘)’的情况会特判
string num(int * i){       // 获取当前位置往后得属于数字部分的字符串
    int pos = *i;
    int begin = pos;
    while((str[pos]=='.'||(str[pos] >= '0' && str[pos] <= '9')) && pos < str.length()) pos ++;
    *i = pos - 1;
    return str.substr(begin,pos - begin);
}
int turn(char x){
    if(x == '#') return 4;
    if(x == '+') return 0;
    if(x == '-') return 1;
    if(x == '*') return 2;
    if(x == '/') return 3;
    if(x == '(') return 5;
}
int check(char a,char b){  // 判断优先级的函数
     int n = turn(a);
     int m = turn(b);
     return judge[n][m];
}
int main(){
    stack<string> a;
    stack<string> b;
    b.push("#");
    cin >> str;
    for(int i = 0;i < str.length();i ++){
        if(str[i] == '(') b.push(str.substr(i,1));
        else if((str[i - 1]=='('|| i == 0)&&(str[i] < '0' || str[i] > '9')){
                i += 1;
                a.push(str[i - 1] + num(&i));
        }
        else if(str[i] <= '9' && str[i] >= '0'){
            string now = num(&i);
            a.push(now); 
        }
        else {
            if(str[i]=='(') b.push(str.substr(i,1));
            else if(str[i]==')'){
                    while(b.top()!="("){
                        string now = b.top();
                        b.pop();
                        a.push(now);
                    }
                    b.pop();
            }
            else if(check(str[i],b.top()[0]) > 0){
                    b.push(str.substr(i,1));
            }
            else {
                while((check(str[i],b.top()[0]) <= 0)&&b.top() != "("){
                    string now = b.top();
                    b.pop();
                    a.push(now);
                }
                b.push(str.substr(i,1));
            }
        }
    }
    while(b.top() != "#"){
        string now = b.top();
        b.pop();
        a.push(now);
    }
    stack<string> ans;
    while(!a.empty()){
        string now = a.top();
        a.pop();
        ans.push(now);
    }
    while(!ans.empty()){
        if(ans.top()==")"||ans.top()=="("){
            ans.pop();
            continue;
        }
        if(ans.top()[0] == '+'&&ans.top().length() > 1)
            ans.top().erase(0,1);
        cout << ans.top();
        if(ans.size() > 1) cout << " ";
        ans.pop();
    }
    return 0;
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值