【C++】中缀表达式转化为后缀表达式(带字母、正负数)

问题:给定一个可能包含字母、数字(正负数)的中缀表达式,请将其转化为后缀表达式

· 核心思想:利用栈来实现该操作。

1.数据准备:

首先定义两个string类型的变量str和ans,分别用来存储所给的中缀表达式和最后要输出的后缀表达式。

定义一个栈stk,用来执行中缀变后缀的相关操作。

2.判定优先级:

在前缀转中缀的过程中,是通过计算各运算符的优先级来进行的,因此需要设计一个函数,用来判定某个运算符的优先级。

预设“+”和“-”的优先级为2,“*”和“/”的优先级为3,“^”的优先级为4,其余如括号等的优先级设定为1.

因此,传入所给的运算字符ch,通过该函数,可依据ch的类型返回其优先级。

3.算法思想:

①去除所给表达式str中的所有空格;

②遍历str表达式:

· 如果检测到数字或字母,直接加入后缀表达式中;

· 如果检测到字符,判定其类型:

若为“(”,入栈;若为“)”,则依次将栈中的运算符加入后缀表达式,直到出现“(”,并从栈中删除“(”。

若为“+”,则首先判定其是否是“表示正数”的加号。若其为运算加号,则判定是否高于栈顶元素优先级,高于则入栈;若为“-”,则首先判定其是否是“表示负数”的减号。若其为运算减号,则判定是否高于栈顶元素优先级,高于则入栈;若为其余运算符,直接判断是否高于栈顶元素优先级,高于则入栈。

若“+”、“-”、其余运算符优先级低于栈顶元素,则依次弹出栈顶运算符并加入后缀表达式,直到一个优先级比它低的运算符或“(”为止。

③遍历完成,若栈非空,依次弹出栈中所有元素并加入后缀表达式。

该算法使得栈顶运算符处于较高优先级,并先弹出栈,进入后缀表达式。在执行完上述操作后,也就得到了最后要转化的后缀表达式。

难点:

假若给予的中缀表达式包含正负数,如何判断正号符号表示的是运算还是正负数的判定符

假若给予的中缀表达式存在空格,如何消除空格影响

代码:

#include <bits/stdc++.h>

using namespace std;

// 判定运算符的优先级
int prior(char x)
{
    if(x=='*'||x=='/') return 3;
    else if(x=='+'||x=='-') return 2;
    else if(x=='^') return 4;
    else return 1;
}

void solve()
{
    string str;
    string ans;
    // 用getline读入表达式,防止空格影响
    getline(cin, str);
    // 去除表达式里的空格
    str.erase(remove(str.begin(), str.end(), ' '), str.end());

    stack<char> stk;
    // 遍历表达式,执行转化操作
    for(int i = 0;i < str.size();i++)
    {
        char ch = str[i];
        // 如果是数字、字母,则直接加到后缀表达式里
        if(ch >= '0' && ch <= '9')
        {
            ans += ch;
        }
        else if(ch >= 'A' && ch <= 'Z')
        {
            ans += ch;
        }
        else if(ch >= 'a' && ch <= 'z')
        {
            ans += ch;
        }
        else
        {
            // 如果是'(',直接入栈
            if(ch == '(')
            {
                stk.push(ch);
            }
            // 如果是')',则将栈中运算符依次读出,加入后缀表达式,直到遇到'('或栈空
            else if(ch == ')')
            {
                while(!stk.empty() && stk.top() != '(')
                {
                    ans += stk.top();
                    stk.pop();
                }
                // 别忘了弹出最后的左括号
                stk.pop();
            }
            // 如果是减号,先要判定是表示运算还是表示正负数
            else if(ch == '-')
            {
                // 如果是表示正负号,直接加入表达式
                if(!(str[i-1] >= '0' && str[i-1] <= '9'))
                {
                    ans += '-';
                }
                // 如果是表示运算,就判定其优先级,直到遇到优先级更低的运算符或'('
                else
                {
                    while(!stk.empty() && stk.top() != '(')
                    {
                        if(prior(stk.top()) >= prior(ch))
                        {
                            ans += stk.top();
                            stk.pop();
                        }
                        else
                            break;
                    }
                    stk.push(ch);
                }
            }
            // 加号和减号同理
            else if(ch == '+')
            {
                if(!(str[i-1] >= '0' && str[i-1] <= '9'|| str[i-1] == ')'))
                {
                    continue;
                }
                else
                {
                    while(!stk.empty() && stk.top() != '(')
                    {
                        if(prior(stk.top()) >= prior(ch))
                        {
                            ans += stk.top();
                            stk.pop();
                        }
                        else
                            break;
                    }
                    stk.push(ch);
                }
            }
            // 如果是剩下的运算符
            else
            {
                while(!stk.empty() && stk.top() != '(')
                {
                    if(prior(stk.top()) >= prior(ch))
                    {
                        ans += stk.top();
                        stk.pop();
                    }
                    else
                        break;
                }
                stk.push(ch);
            }
        }
    }
    // 最后将栈中剩余的元素全部弹出
    while(!stk.empty())
    {
        ans += stk.top();
        stk.pop();
    }

    cout << ans << endl;
//    测试用
//    cout << str << endl;
}

int main()
{
    int t = 1;

    for(int i = 1;i <= t;i++)
    {
        solve();
    }

    return 0;
}

如有问题,随时欢迎指出~(՞• •՞)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值