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

时间:2022-12-16 22:27:10


算术表达式的转换

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;
}