中缀表达式转后缀表达式的原理
入栈的几种情况:1,栈为空
2.入栈元素的优先级比栈栈顶元素高
3.入栈的元素为‘(’(注意:当入栈元素为’)'号时会输出栈中元素直到遇到‘(’)
代码思路
分为一下几种情况:
1.输入字符为数字
2.输入字符为‘)’
3.输入字符为+、-
4.输入字符为*、/、(
5.其他情况,非法输入
1.下面展示在C环境中的代码
:
#include <stdio.h>
#include <stdbool.h>
#define Maxsize 100
//以上是用宏定义一个Maxsize为100
typedef char ElemType; //将数据类型char命名一个别名ElemType,可以理解为ElemType等同于char
typedef struct { //定义一个名为SqStack的结构体类型,date[Maxsize]用来元素,top表示数组最后一位元素的下标,也就是栈顶元素下标
ElemType date[Maxsize];
int top;
}SqStack;
void InitStack(SqStack* S) { //对结构体进行初始化
S->top = -1; //将栈顶元素下标初始化为-1,表示当前栈内元素为空,
}
bool StackEmpty(SqStack S) { //判断结构体是否为空,为空返回true,不为空返回false
if (-1 == S.top)
return true;
else
return false;
}
bool PushStack(SqStack* S, ElemType m) { //添加元素进栈,添加成功返回true,添加失败返回false,
if (S->top <= Maxsize - 1) //栈未满,元素可以放进栈中
{
S->date[++(S->top)] = m; //这段代码可以分两步理解,S.top++;S.date[S.top]=m;
return true;
}
else
return false;
}
bool GetStack(SqStack S,ElemType* m) { //获取栈顶元素,并将栈顶元素赋值给m
if (S.top != -1) //判断栈不为空
{
*m = S.date[S.top]; //将栈顶元素赋值给m
return true;
}
else
return false;
}
bool PopStack(SqStack* S,ElemType* m) { //弹栈,将栈顶元素从栈中取出,添加成功返回true,添加失败返回false,
if (-1 != S->top) //判断栈不为空
{
*m = S->date[(S->top)--]; //同样这里可以分两步理解,m=S.date[S.top];S.top--;
return true;
}
else
return false;
}
int main() {
SqStack S; //定义一个SqStack类型的结构体S
InitStack(&S); //初始化栈
char c, e; //定义两个char类型的变量,当然用ElemType也可以
printf("请输入表达式: ");
while ((c=getchar())!='\n') { //我们在键盘输入的数据也就是表达式会放在缓冲区,这里使用的是getchar获取缓冲区的表达式,并且一次只会获取一个字符直到获取到换行符或文件结束符EOF,结合使用循环遍历整个表达式
if (c >= '0' && c <= '9') //判断如果读取字符c是数字则直接打印,知识点补充:整数放进字符中以ascll码表示
printf("%c", c);
else if (')' == c){ //如果是c为')',则直接输出栈中元素,直到遇到'('
PopStack(&S, &e); //取出栈中元素
while ('(' !=e ) { //判断取出的栈中元素是否为'(',不是就继续打印
printf("%c",e);
PopStack(&S,&e);
}
}
else if('+'==c||'-'==c) { //判断读取的字符c是否为—或+
if (-1 == S.top) //栈若为空,直接将字符c放入栈中
PushStack(&S, c);
else //栈若不为空,使用do-while输出栈中元素,do-while相比while的先判断再操作的方式相反,do-while是先操作再判断
{
do {
PopStack(&S,&e); //先取出栈中元素
if ('(' == e) //判断取出的栈中元素是否为'(',若是,则将e重新入栈
PushStack(&S, e);
else //取出的栈中元素不是'('因此直接打印
printf("%c",e);
} while (!StackEmpty(S)&&'('!=e); //do-while的判断栈不为空且栈顶元素不等于'(',继续操作;
PushStack(&S,c); //将读取到的字符c入栈
}
}
else if ('*'==c||'/'==c||'('==c) { //判断获取到的元素是否为*、/、'('
if (S.top < Maxsize - 1) //若栈未满,则做进一步判断,
{
GetStack(S,&e); //获取栈顶元素,并将栈顶元素赋值给e
if ('*' == e || '/' == e) { //判断栈顶元素是否为*或/,若是,则在随后的do-while中做进一步操作
do {
PopStack(&S, &e); //取出栈顶元素
printf("%c", e); //打印取出的栈顶元素
} while ('*' == c && '/' == c); //do-while的判断条件
PushStack(&S,c); //将获取的字符c放入栈中
}
else //若栈顶元素不为*也不为/,则将获取的字符放入栈中
{
PushStack(&S, c);
}
}
else //栈满因此无法将元素放入栈中
printf("栈已满,无法放入!");
}
else //以上的情况都没有出现,则为非法输入并返回-1结束程序
{
printf("\n输入的字符非法!!");
return -1;
}
}
while (-1 != S.top) //当获取的元素都处理完成后,若栈不为空遍历整个栈并输出栈中的内容
{
PopStack(&S,&e);
printf("%c",e);
}
return 0;
}
2.下面展示在C++环境中的代码
:
#include <stdio.h>
#include <stdlib.h>
#define Maxsize 100
//以上是用宏定义一个Maxsize为100
typedef char ElemType; //将数据类型char命名一个别名ElemType,可以理解为ElemType等同于char
typedef struct { //定义一个名为SqStack的结构体类型,date[Maxsize]用来元素,top表示数组最后一位元素的下标,也就是栈顶元素下标
ElemType date[Maxsize];
int top;
}SqStack;
void InitStack(SqStack& S) { //对结构体进行初始化
S.top = -1; //将栈顶元素下标初始化为-1,表示当前栈内元素为空,
}
bool StackEmpty(SqStack S) { //判断结构体是否为空,为空返回true,不为空返回false
if (-1 == S.top)
return true;
else
return false;
}
bool PushStack(SqStack& S, ElemType m) { //添加元素进栈,添加成功返回true,添加失败返回false,
if (S.top <= Maxsize - 1) //栈未满,元素可以放进栈中
{
S.date[++S.top] = m; //这段代码可以分两步理解,S.top++;S.date[S.top]=m;
return true;
}
else
return false;
}
bool GetStack(SqStack S,ElemType &m) { //获取栈顶元素,并将栈顶元素赋值给m,m的值会发生改变因此这里使用了&,特别说明C++的&类似于C语言中指针,同样添加成功返回true,添加失败返回false,
if (S.top != -1) //判断栈不为空
{
m = S.date[S.top]; //将栈顶元素赋值给m
return true;
}
else
return false;
}
bool PopStack(SqStack &S,ElemType &m) { //弹栈,将栈顶元素从栈中取出,添加成功返回true,添加失败返回false,
if (-1 != S.top) //判断栈不为空
{
m = S.date[S.top--]; //同样这里可以分两步理解,m=S.date[S.top];S.top--;
return true;
}
else
return false;
}
int main() {
SqStack S; //定义一个SqStack类型的结构体S
InitStack(S); //初始化栈
char c, e; //定义两个char类型的变量,当然用ElemType也可以
printf("请输入表达式: ");
while ((c=getchar())!='\n') { //我们在键盘输入的数据也就是表达式会放在缓冲区,这里使用的是getchar获取缓冲区的表达式,并且一次只会获取一个字符直到获取到换行符或文件结束符EOF,结合使用循环遍历整个表达式
if (c >= '0' && c <= '9') //判断如果读取字符c是数字则直接打印,知识点补充:整数放进字符中以ascll码表示
printf("%c", c);
else if (')' == c){ //如果是c为')',则直接输出栈中元素,直到遇到'('
PopStack(S, e); //取出栈中元素
while ('(' !=e ) { //判断取出的栈中元素是否为'(',不是就继续打印
printf("%c",e);
PopStack(S,e);
}
}
else if('+'==c||'-'==c) { //判断读取的字符c是否为—或+
if (-1 == S.top) //栈若为空,直接将字符c放入栈中
PushStack(S, c);
else //栈若不为空,使用do-while输出栈中元素,do-while相比while的先判断再操作的方式相反,do-while是先操作再判断
{
do {
PopStack(S,e); //先取出栈中元素
if ('(' == e) //判断取出的栈中元素是否为'(',若是,则将e重新入栈
PushStack(S, e);
else //取出的栈中元素不是'('因此直接打印
printf("%c",e);
} while (!StackEmpty(S)&&'('!=e); //do-while的判断栈不为空且栈顶元素不等于'(',继续操作;
PushStack(S,c); //将读取到的字符c入栈
}
}
else if ('*'==c||'/'==c||'('==c) { //判断获取到的元素是否为*、/、'('
if (S.top < Maxsize - 1) //若栈未满,则做进一步判断,
{
GetStack(S,e); //获取栈顶元素,并将栈顶元素赋值给e
if ('*' == e || '/' == e) { //判断栈顶元素是否为*或/,若是,则在随后的do-while中做进一步操作
do {
PopStack(S, e); //取出栈顶元素
printf("%c", e); //打印取出的栈顶元素
} while ('*' == c && '/' == c); //do-while的判断条件
PushStack(S,c); //将获取的字符c放入栈中
}
else //若栈顶元素不为*也不为/,则将获取的字符放入栈中
{
PushStack(S, c);
}
}
else //栈满因此无法将元素放入栈中
printf("栈已满,无法放入!");
}
else //以上的情况都没有出现,则为非法输入并返回-1结束程序
{
printf("\n输入的字符非法!!");
return -1;
}
}
while (-1 != S.top) //当获取的元素都处理完成后,若栈不为空遍历整个栈并输出栈中的内容
{
PopStack(S,e);
printf("%c",e);
}
return 0;
}