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

7-20 表达式转换 (25 分)

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

输入格式:

输入在一行中给出不含空格的中缀表达式,可包含+-*\以及左右括号(),表达式不超过20个字符。

输出格式:

在一行中输出转换后的后缀表达式,要求不同对象(运算数、运算符号)之间以空格分隔,但结尾不得有多余空格。

输入样例:

2+3*(7-4)+8/4

输出样例:

2 3 7 4 - * + 8 4 / +

注意:表达式中有正负号,括号,多位数。

问题:将中缀表达式转化为后缀表达式:中缀表达式是一个字符串,其中有正负数,多位数和();

设计方案:遍历字符串。字符串中数字的相对位置不会改变,但是符号会入一个新栈,若栈为空,直接入栈,若不是判断此刻的符号和栈顶符号的优先级,若此刻的优先级比较低,则栈顶的符号可以跟在数字栈中最上面两个元素的后面,若此刻的优先级比较高,则加入到符号栈。如果遇到(,将他入栈且他后面紧邻的符号也要入栈,遇到)则将)前面的元素一个个弹出到数字的后面。如果字符串都遍历完了且字符栈不为空,则按从后向前的顺序将剩下的符号弹出到结果的最后。

对于正负号的判断:有加减号且加减号前面是非字符和非‘)’时不是加减法。

多位数:用流stringstream可以自动识别浮点数和整型数。但只能识别开头就是+-或整数的字符串,用substr解决这一问题,多位数和符号都用string来存储入栈。

代码

#include<iostream>
#include<stack>
#include<map>
#include<sstream>
#include<vector>
using namespace std;
map<char,int>mp;

int cmp(char a,char b)
{
    if(a==')'&&b=='(')
        return 0;
    else if(mp[a]!=mp[b])
        return mp[a]-mp[b];
    else if(mp[a]==mp[b])
        return -1;
}
char stringToChar(string s)
{
    return s[0];
}
string charToString(char c)
{
    string s;
    s.push_back(c);
    return s;
}
int main()
{
    char a[21];
    mp['-']=1;
    mp['+']=1;
    mp['(']=3;
    mp[')']=0;
    mp['*']=2;
    mp['/']=2;
    string s;
    cin>>s;
    int i;
    stack<string>op,opd,res;
    stringstream s1,s2;
    s1.str(s);
    for(i=0; i<s.size(); i++)
    {
        if((i-1>=0&&i+1<s.size()&&!isdigit(s[i-1])&&s[i-1]!=')'&&(s[i]=='-'||s[i]=='+')&&isdigit(s[i+1]))||isdigit(s[i])||(i==0&&(s[i]=='-'||s[i]=='+')))
        {
            double a;
            string x;
            s1.str(s.substr(i,s.size()-i));
            s1>>a;
            s2.str("");
            s2<<a;
            x=s2.str();
            opd.push(x);
            res.push(x);
            i+=x.size()-1;
           while(isdigit(s[i+1])||s[i+1]=='.')
           i+=1;
        }
        else
        {
            if(!op.empty())
            {
                while(!op.empty()&&cmp(s[i], stringToChar(op.top()))<=-1&&stringToChar(op.top())!='(')  //新的比栈顶优先级低
                {
                    res.push(op.top());
                    op.pop();
                }
                if(!op.empty())
                {
                    if(cmp(s[i],stringToChar(op.top()))==0)
                    {
                        op.pop();
                    }
                    else if(cmp(s[i],stringToChar(op.top()))>=1||stringToChar(op.top())=='(')
                    {
                        op.push(charToString(s[i]));
                    }
                }
                else
                    op.push(charToString(s[i]));
            }
            else
                op.push(charToString(s[i]));
        }
    }
    while(!op.empty())
    {
        res.push(op.top());
        op.pop();
    }
    int k=0;
    vector<string>v;
    while(!res.empty())
        {
           v.push_back(res.top());
        res.pop();
        k++;
        }
    for(i=k-1; i>=0; i--)
    {
        if(i==k-1)
            cout<<v[i];
        else
            cout<<" "<<v[i];
    }
    cout<<endl;
}

猜你喜欢

转载自blog.csdn.net/weixin_42165786/article/details/83062075