暑假集训 8.6 sdutoj2484 算术表达式的转换(模拟栈;前中后缀转换)


算术表达式的转换

Time Limit: 1000MS Memory limit: 65536K

题目描述

小明在学习了数据结构之后,突然想起了以前没有解决的算术表达式转化成后缀式的问题,今天他想解决一下。
   因为有了数据结构的基础小明很快就解出了这个问题,但是他突然想到怎么求出算术表达式的前缀式和中缀式呢?小明很困惑。聪明的你帮他解决吧。

输入

 输入一算术表达式,以\'#\'字符作为结束标志。(数据保证无空格,只有一组输入)

输出

 输出该表达式转换所得到的前缀式 中缀式 后缀式。分三行输出,顺序是前缀式 中缀式 后缀式。

示例输入

a*b+(c-d/e)*f#

示例输出

+*ab*-c/def
a*b+c-d/e*f
ab*cde/-f*+

///这道题真是刻苦铭心啊233333卡了好长时间的....

///后缀表达式前面有 才改的...

///中缀表达式就是把括号去掉...木有问题...

///前缀跟后缀差不多 但是前缀需要运算符栈(s)和数字栈(num)  

///主要思路  : i. 栈外元素优先级(仅限于运算符号比较且设括号优先级最低)高于等于s栈顶元素 栈外元素进s栈 ii. 低于时 while() :s栈顶元素出栈压入num栈,一直到 i. 成立;


///中缀转化为前缀表达式步骤如下(字符数组逆序读入)

///1.如果字符数组读入是数字符号 压入num栈for(;;) :step1~5

///2.如果读入是右括号或者s栈空 压入s栈

///3.如果读入是左括号 3-1 while() :s 元素出栈 并且压入num栈 直至s栈顶右括号 3-2 舍弃右括号

///4.如果读入是 + 或者 - :只要s栈顶不是括号是其他的运算符(* / ) :while() :s栈顶元素出栈压入num栈;一直到s栈顶是括号后栈外元素压入s栈

///5.如果读入是 * 或者 /  :直接压入s栈

#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
using namespace std;

const int  maxsize = 10000;

typedef struct Stack
{
    int Size;
    char *top,*base;///equal  char  base[]
} Stack;

bool Empty(Stack &s)  ///判断是否为空
{
    if (s.top == s.base)
    {
        return 1;
    }
    return 0;
}

void Creat(Stack &s)  ///建立空栈
{
    s.base=new char[maxsize];
    s.top=s.base;
    s.Size=maxsize;
}

bool flag(char ch) ///判断是不是 数字符号
{
    if (ch=='+'||ch=='-'||ch=='*'||ch=='/'||ch=='('||ch==')')
    {
        return 0;
    }
    return 1;
}

void push(Stack &s,char e)  ///压e入栈
{
    if (s.top-s.base >= s.Size)
    {
        s.base=(char *)realloc(s.base,2*maxsize*sizeof(Stack)); ///防止内存不够...
        s.Size+=maxsize;
    }
    s.top++;
    *s.top=e;
}

void pop(Stack &s) ///出栈
{
    if (s.top != s.base)
    {
        s.top--;
    }
}

void print(Stack &s) ///栈打印
{
    while (!Empty(s))
    {
        cout<<*s.top;
        pop(s);
    }
    cout<<endl;
}


void Clear(Stack &s) ///栈清空
{
    while (!Empty(s))
    {
        pop(s);
    }
}

void last(Stack &s,char st[],int n) ///后序
{
    int i;
    for (i=1; i<=n; i++)
    {
        if (flag(st[i]))
        {
            cout<<st[i];
        }
        else
        {
            if (Empty(s))
            {
                s.top++;
                *s.top=st[i];
            }
            else
            {
                if (st[i]=='(')
                {
                    s.top++;
                    *s.top=st[i];
                }
                else if (st[i]=='+'||st[i]=='-')
                {
                    while (*s.top=='/'||*s.top=='*'||*s.top=='+'||*s.top=='-')
                    {
                        cout<<*s.top;
                        pop(s);
                    }
                    push(s,st[i]);
                }
                else if (st[i]=='/'||st[i]=='*')
                {
                    while (*s.top=='/'||*s.top=='*')
                    {
                        cout<<*s.top;
                        pop(s);
                    }
                    push(s,st[i]);
                }
                else if (st[i]==')')
                {
                    while(*s.top!='(')
                    {
                        cout<<*s.top;
                        pop(s);
                    }
                    pop(s);
                }
            }
        }
    }
}

void pre(Stack &num,Stack &s,char st[],int n)   ///前序
{
    int i;
    for (i=n; i>=1; i--)
    {
        if (flag(st[i]))   ///step 1
        {
            push(num,st[i]);
        }
        else
        {
            if (Empty(s)) ///step 2
            {
                push(s,st[i]);
            }
            else
            {
                if (st[i]==')')    ///step 2
                {
                    push(s,st[i]);
                }
                else if (st[i]=='+'||st[i]=='-')  ///step 4
                {
                    while (*s.top=='/'||*s.top=='*')
                    {
                        push(num,*s.top);
                        pop(s);
                    }
                    push(s,st[i]);      ///一旦跳出while则st[i]入s栈
                }
                else if (st[i]=='/'||st[i]=='*')  ///step 5 
                {
                    push(s,st[i]);
                }
                else if (st[i]=='(')   ///step 3
                {
                    while(*s.top!=')')
                    {
                        push(num,*s.top);
                        pop(s);
                    }
                    pop(s);  ///step 3-2
                }
            }

        }
    }
    while (!Empty(s))
    {
        push(num,*s.top);
        pop(s);
    }
}

void mid(char s[],int n) ///中序
{
    int i;
    for (i=1; i<=n; i++)
    {
        if (s[i]!='('&&s[i]!=')')
        {
            cout<<s[i];
        }
    }
    cout<<endl;
}

int main()
{
    char str[maxsize],ch;
    int i=0;
    Stack s,num;///signal and number’s stack

    Creat(s);
    Creat(num);

    while(ch=getchar())
    {
        if(ch!='#')  ///以 # 作为输入结束
        {
            i++;
            str[i]=ch;
        }
        else break;
    }

    pre(num,s,str,i); ///此时的i从1开始 i 最后为字符数组长度 即 “下标”1--i;
    print(num);

    mid(str,i);

    Clear(s);
    last(s,str,i);
    print(s);

    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值