【pta】7-20 表达式转换 (25 分) <中缀转后缀>

一、题目大意

题目链接:https://pintia.cn/problem-sets/15/problems/827

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

输入格式:

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

输出格式:

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

输入样例:

2+3*(7-4)+8/4
 
结尾无空行

输出样例:

2 3 7 4 - * + 8 4 / +
 
结尾无空行

二、第一版代码

#include <bits/stdc++.h>
using namespace std;

int main(void)
{
    stack<char>st;
    string s;
    cin>>s;
    int flag=0;
    for (int i=0;i<s.size();i++)
    {
        if (s[i]>='0'&&s[i]<='9')
        {
            if (flag)
            {
                printf("%c",s[i]);
                flag=0;
            }
            else
            {
                if (i) printf(" ");
                printf("%c",s[i]);
            }
        }
        else if (st.empty())
        {
            if (s[i]=='+'&&i==0) continue;
            else if (s[i]=='+'&&s[i-1]=='(') continue;
            else if (s[i]=='-'&&i==0) printf(" %c",s[i]),flag=1;
            else if (s[i]=='-'&&s[i-1]=='(') printf(" %c",s[i]),flag=1;
            else st.push(s[i]);
        }
        else if (s[i]=='*'||s[i]=='/')
        {
            if (st.top()=='+'||st.top()=='-'||st.top()=='(') st.push(s[i]);
            else
            {
                if (i) printf(" ");
                printf("%c",st.top());
                st.pop();
                st.push(s[i]);
            }
        }
        else if (s[i]=='+'||s[i]=='-')
        {
            if (s[i-1]=='(')
            {
                if (s[i]=='+') continue;
                else printf(" %c",s[i]);
                flag=1;
                continue;
            }
            while (st.top()!='+'&&st.top()!='-'&&st.top()!='(')
            {
                if (i) printf(" ");
                printf("%c",st.top());
                st.pop();
            }
            if (st.top()=='('||st.empty()) st.push(s[i]);
            else
            {
                if (i) printf(" ");
                printf("%c",st.top());
                st.pop();
                st.push(s[i]);
            }
        }
        else if (s[i]=='(') st.push(s[i]);
        else if (s[i]==')')
        {
            while (st.top()!='(')
            {
                if (i) printf(" ");
                printf("%c",st.top());
                st.pop();
            }
            st.pop();
        }
        else if (s[i]=='.')
        {
            printf("%c",s[i]);
            flag=1;
        }
    }
    while (!st.empty())
    {
        printf(" %c",st.top());
        st.pop();
    }
    return 0;
}

 

 

 当时的大无语事件

后来看到了大佬写的文章,大受震撼,好像确实有很多点都没考虑到(当时小数和负数都没想到)

https://blog.csdn.net/SiKongPop/article/details/77972879

后来改了一下终于ac

三、ac代码

#include <bits/stdc++.h>
using namespace std;

int main(void)
{
    stack<char>st;
    string s;
    cin>>s;
    int flag=1; //第二个测试点的坑,(嵌套括号),这样任何情况第一个数字都会直接输出
    for (int i=0;i<s.size();i++)
    {
        if (s[i]>='0'&&s[i]<='9')
        {
            if (flag)  //遇到特殊情况,eg:0.5,-2
            {
                printf("%c",s[i]);
                flag=0;
                continue;
            }
            if (s[i-1]<'0'||s[i-1]>'9') // eg:-25
            {
                if (i) printf(" ");
                printf("%c",s[i]);
            }
            else if (s[i+1]>='0'&&s[i+1]<='9'||s[i-1]>='0'&&s[i-1]<='9') //eg:123
            {
                printf("%c",s[i]);
            }
        }
        else if (st.empty())
        {
            if (s[i]=='+'&&i==0) continue; //eg:+5*10
            else if (s[i]=='-'&&i==0) printf("%c",s[i]),flag=1; //eg:-5+1
            else st.push(s[i]);
        }
        else if (s[i]=='*'||s[i]=='/')
        {
            if (st.top()=='+'||st.top()=='-'||st.top()=='(') st.push(s[i]); //优先级高的推入
            else
            {
                if (i) printf(" ");
                printf("%c",st.top());
                st.pop();
                st.push(s[i]);
            }
        }
        else if (s[i]=='+'||s[i]=='-')
        {
            if (s[i-1]=='(')
            {
                if (s[i]=='+') continue; //eg:(+5)+2
                else
                {
                    if (i) printf(" ");  //eg:(-5+1)+2
                    printf("%c",s[i]);
                    flag=1;
                    continue;
                }
            }
            while (st.top()!='+'&&st.top()!='-'&&st.top()!='(') //直到栈内优先级和当前一样,或更低
            {
                if (i) printf(" ");
                printf("%c",st.top());
                st.pop();
            }
            if (st.top()=='('||st.empty()) st.push(s[i]); //栈内优先级比当前低,或者栈空了
            else
            {
                if (i) printf(" ");
                printf("%c",st.top());  //把栈顶的输出,并推入当前符号
                st.pop();
                st.push(s[i]);
            }
        }
        else if (s[i]=='(') st.push(s[i]); //栈内'('优先级最低,直接推入
        else if (s[i]==')') //将栈顶元素输出并推出,直到找到'('
        {
            while (st.top()!='(')
            {
                if (i) printf(" ");
                printf("%c",st.top());
                st.pop();
            }
            st.pop();
        }
        else if (s[i]=='.') //判定小数部分
        {
            printf("%c",s[i]);
            flag=1;
        }
    }
    while (!st.empty()) //将栈内剩余元素依次输出
    {
        printf(" %c",st.top());
        st.pop();
    }
    return 0;
}

 

 

注释写的挺详细了,这里不过多赘述,这道题按照知识点正常模拟即可

四、亿些知识点

 

 

 

 

 

何钦铭老师yyds

感谢所有大佬的文章思路和代码

peace

posted @ 2021-09-11 11:40  北辰ฅ  阅读(429)  评论(0)    收藏  举报