(一道老坑爹的题)第三章栈作业题2-栈及其应用-计算机17级 7-1 表达式转换 (25 分)

版权声明:欢迎转载,但转载时请注明原文地址 https://blog.csdn.net/weixin_42110638/article/details/83089498

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

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

输入格式:

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

输出格式:

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

输入样例:

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

输出样例:

2 3 7 4 - * + 8 4 / +

 思路:mooc上的思路

从头到尾读取中缀表达式的每个对象,对不同对象按不同的情况处理。

1.运算数:直接输出

2.左括号:压入栈中

3.右括号:将栈顶的运算符弹出并输出,直到遇到左括号(出栈,不输出)

4.运算符:

若优先级大于栈顶运算符时,则把它压栈;

若优先级小于等于栈顶运算符时,将栈顶运算符弹出并输出;再比较新的栈顶运算符,直到该运算符大于栈顶运算符优先级为止,然后将该运算符压栈

5.若各对象处理完毕,则把堆栈中存留的运算符一并输出

mooc思路补充:其实mooc上的思路完全没问题,但具体实现的过程还会有很多坑,在这里做一些补充

1.碰到数字直接输出,但是这里的数字可能是小数、负数(负号和数字是一起输出的)或带正号的数字;

小数的实现代码里有解释,仔细看应该ok

关于正负号与数字一起输出有两种特殊情况

第一种是正负号在第一位,例如:-1+2-1,此时负号要连着数字一起输出,而如果第一位是正的则不用。

第二种是左括号连着正负号,例如:1+(-2-1)或者2+(+5)-1,此时左括号后的负号也要连着输出,而左括号后的正号则不用

2.把算法代码分为两类,一类是数字类,一类是运算符类,其中关于正负号与数字一起输出我们放在数字类,这属于一种特殊情况的讨论,而其余的情况当做运算符处理即可。所以数字类包括整数,小数,以及那两种特殊情况,而运算符类则包括左括号,右括号,以及加减乘数符号。这样的话代码的逻辑会很清晰

if()//数字类

{

}

else//运算符类

{

}

3.关于运算符的优先级,可以用map映射来表示,加减都设为1,乘除都设为2

4.一下这种代码要记得判空在前,顺序很重要

这是网上找的测试样例

话说这个题我之前是先实现堆栈再来做题的,毕竟数据结构学的就是这个嘛,但是用堆栈真的心累,卡了四天了,一直是段错误,实在是找不出来啊。。。所以这个题建议还是使用stl吧,方便太多了hh。。。当然我会把我那个全是段错误的题代码发出来,欢迎大佬们帮忙修改

先是stl写的正确的代码

#include<bits/stdc++.h>
using namespace std;
stack<char> sta;
map<char,int> ma;//


int main()
{
    ma['+'] = ma['-'] = 1;
    ma['*'] = ma['/'] = 2;
    string ss;
    cin>>ss;
    bool isfirst = true;
    for(int i = 0;ss[i]; i++)
    {
        //判断数字及特殊情况
        //判断ss为整数,为小数点,以及跟正负号与数字一起输出有关的两种特殊情况
        if((isdigit(ss[i])) || (ss[i]=='.') || ((i==0||ss[i-1]=='(') && (ss[i]=='+' || ss[i]=='-')))
        {
            if(!isfirst)//用来控制格式
            {
                cout<<" ";
            }
            if(ss[i]!='+')//负数时直接输出负号,正数则不用
            {
                cout<<ss[i];
            }
            while(ss[i+1]=='.'||isdigit(ss[i+1]))//如果是小数就继续往后读,之后自然会跳出这个循环
            {
                i++;
                cout<<ss[i];
            }
            isfirst = false;

        }
        else//为运算符时
        {
//cout<<" GG "<<i<<endl;
            if(ss[i]=='(')//左括号:压入栈中
            {
                sta.push(ss[i]);
            }
            else if(ss[i]==')')//右括号:将栈顶的运算符弹出并输出,直到遇到左括号(出栈,不输出)
            {
                while(!sta.empty() && sta.top()!='(')
                {
                    cout<<" "<<sta.top();
                    sta.pop();
                }
                sta.pop();
            }
            else if(sta.empty() ||(ma[ss[i]] > ma[sta.top()]))//ss[i]的优先级比栈顶元素的大
            {
                sta.push(ss[i]);
            }
            else
            {
                while(!sta.empty() && sta.top()!='(')//ss[i]的优先级比栈顶元素的小或等
                {
                    cout<<' '<<sta.top();
                    sta.pop();
                }
                sta.push(ss[i]);
            }
        }
    }
    while(!sta.empty())//最后把堆栈中存留的运算符一并输出
    {
        cout<<" "<<sta.top();//注意此时不需要用flag控制格式,因为判断数字那块一定已经有了输出
        sta.pop();
    }
    return 0;
}

然后就是用实现栈写的,答案是对的,但就是运行时他会卡一下,然后交上去一堆段错误。。。求大佬指点!!!

#include<cstdio>
#include<bits/stdc++.h>
#define STACK_INIT_SIZE 1000000
#define STACKINCREMENT 100000
#define TRUE        1
#define FALSE       0
#define OK          1
#define ERROR       0
#define INFEASIBLE -1
//#define OVERFLOW   -2
using namespace std;
typedef char SElemType,Status;

map<char,int> ma;//


typedef struct
{
    SElemType *base;
    SElemType *top;
    int stacksize;
} SqStack;

Status InitStack(SqStack &S)
{
    S.base = (SElemType*)malloc(sizeof(SElemType)*STACK_INIT_SIZE);
    //if(!S.base)
    //exit(OVERFLOW);
    S.base = S.top;
    S.stacksize += STACKINCREMENT;
    return OK;
}

Status Push(SqStack &S,SElemType e)
{
    if(S.top - S.base >= S.stacksize)
    {
        S.base = (SElemType*)realloc(S.base,(S.stacksize + STACKINCREMENT)*sizeof(SElemType));
        //if(!S.base)
        //exit(OVERFLOW);
        S.top = S.base + S.stacksize;
        S.stacksize += STACKINCREMENT;
    }
    *S.top++ = e;
    return OK;
}

Status Pop(SqStack &S)
{
    if(S.top==S.base)
        return ERROR;
    return *--S.top;
    //return OK;
}

SElemType GetTop(SqStack &S)
{
    if(S.base==S.top)
        return ERROR;
    return *(S.top-1);
}

bool JudgeEmpty(SqStack &S)
{
    if(S.top == S.base)
        return true;
    else
        return false;
}

//胜利oid PrintStack(SqStack &S);

int main()
{
    SqStack S;
    ma['+'] = ma['-'] = 1;
    ma['*'] = ma['/'] = 2;
    InitStack(S);
    string ss;
    cin>>ss;
    bool isfirst = true;
    for(int i = 0; ss[i]; i++)
    {
        //判断数字及特殊情况
        //判断ss为整数,为小数点,以及跟负号有关的两种特殊情况
        if((isdigit(ss[i])) || (ss[i]=='.') || ((i==0||ss[i-1]=='(') && (ss[i]=='+' || ss[i]=='-')))
        {
            if(!isfirst)
            {
                cout<<" ";
            }
            if(ss[i]!='+')//负数时直接输出负号,正数则不用
            {
                cout<<ss[i];
            }
            while(ss[i+1]=='.'||isdigit(ss[i+1]))
            {
                i++;
                cout<<ss[i];
            }
            isfirst = false;
        }

        else//为运算符时
        {
            if(ss[i]=='(')
            {
                Push(S,ss[i]);
            }
            else if(ss[i]==')')
            {
                while(!JudgeEmpty(S)&&GetTop(S)!='(')
                {
                    cout<<" "<<GetTop(S);
                    Pop(S);
                }
                //if(!JudgeEmpty(S))
                Pop(S);
            }
            else if(ma[ss[i]] <= ma[GetTop(S)])
            {
                while(!JudgeEmpty(S)&&GetTop(S)!='(')
                {
                    cout<<" "<<GetTop(S);
                    Pop(S);
                }
                Push(S,ss[i]);
            }
            else if(JudgeEmpty(S)||(ma[ss[i]] > ma[GetTop(S)]) )//ss[i]的优先级比栈顶元素的大
            {
                Push(S,ss[i]);
            }
        }
    }
    while(!JudgeEmpty(S))
    {
        cout<<" "<<GetTop(S);
        Pop(S);
    }
}

题目链接:https://pintia.cn/problem-sets/434/problems/5893

希望有大佬能帮我解决这个问题,毕竟这几天一直是

。。。 

猜你喜欢

转载自blog.csdn.net/weixin_42110638/article/details/83089498