一、反波兰表达式的转化方法
1.设定运算符栈;
2.从左到右遍历中缀表达式的每个数字和运算符;
3.若当前字符是数字,则直接输出成为后缀表达式的一部分;
4.若当前字符为运算符,则判断其与栈顶运算符的优先级,若优先级大于栈顶运算符,则进栈;若优先级小于等于栈顶运算符,退出栈顶运算符成为后缀表达式的一部分,然后将当前运算符放入栈中,注意,这一步需要重复进行直到当前字符大于栈顶运算符;
5.若当前字符为“(”,进栈;
6.若当前字符为“)”,则从栈顶起,依次将栈中运算符出栈成为后缀表达式的一部分,直到碰到“(”。将栈中“(”出栈,不需要成为后缀表达式的一部分,然后继续扫描表达式直到最终输出后缀表达式为止。
7.最后要把栈中剩余的运算符按顺序全部弹出,加入到后缀表达式!!!
————————————————
版权声明:本文为CSDN博主「JAZHR」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_43290883/article/details/125633103
二、反波兰表达式的转化·示例代码
该段代码用于将中缀表达式转化为后缀表达式
#include
#include
#define MAXSIZE_signStack 100
#define MAXSIZE_INPUT 1000
#define MAXSIZE_OUTPUT 1000
//中缀转后缀函数
char signStack[MAXSIZE_signStack]; //操作符栈
int signtop; //操作符栈栈顶编号
char input[MAXSIZE_INPUT]; //中缀表达式
char output[MAXSIZE_OUTPUT]; //后缀表达式
//中缀转后缀函数以及其附属函数声明
//中缀表达式必须严格存储在input数组中
//后缀表达式必须严格存储在output数组中
//上述两数组的最大值由MAXSIZE_INPUT和MAXSIZE_OUTPUT定义,需要进行define
//需要定义操作符栈数组和操作符栈栈顶编号
void anti_poland_tras();
void initStack(int* ptop);
int isEmpty(int* ptop);
int isFull(int* ptop);
void Error(char *s);
void push_char(char *s,char item,int* ptop);
void pop_char(int* ptop);
int grade(char a);
//栈空判断函数和满栈判断函数可能与其它功能重复,请小心使用
int main(void)
{
//获取中缀表达式
gets(input);
//进行转化为反波兰表达式的运算
anti_poland_tras();
puts(output);
}
//中缀转后缀函数
void anti_poland_tras()
{
//设定运算符栈
initStack(&signtop);
//操作符栈栈底以'#'垫底
push_char(signStack,'#',&signtop);
//遍历中缀表达式
int i;
int j=0;
//j用于记录output数组的长度-1
for (i=0;i='0'&&input[i]<='9')
{
//若当前字符为数字,则直接输出为后缀表达式
output[j++]=input[i];
}
else if (input[i]==' ')
{
//跳过潜在的空格
continue;
}
else if (input[i]=='(')
{
//如果是左引号,直接进栈
push_char(signStack,'(',&signtop);
//读取符号要间隔
output[j++]=' ';
}
else if (input[i]==')')
{
//从栈顶起,依次将运算符出栈后成为后缀表达式的一部分,直到碰到'('。
while(signStack[signtop]!='(')
{
output[j++]=signStack[signtop];
pop_char(&signtop);
}
//'('出栈,但不写入后缀表达式
pop_char(&signtop);
//读取符号要间隔
output[j++]=' ';
}
else
{
//当前字符优先级小于等于栈顶运算符,弹出栈顶运算符并输入至后缀表达式
//重复此操作,直到当前字符优先级大于栈顶运算符
while(grade(input[i])<=grade(signStack[signtop]))
{
output[j++]=signStack[signtop];
pop_char(&signtop);
}
//当前字符优先级大于栈顶运算符,当前字符直接进栈
push_char(signStack,input[i],&signtop);
//读取符号要间隔
output[j++]=' ';
}
}
//最后弹出所有的剩余操作符
while (signtop>0)
{
output[j++]=signStack[signtop];
pop_char(&signtop);
}
}
//建栈函数,参数是指向操作符栈顶编号的指针
void initStack(int* ptop)
{
*ptop=-1;
}
//空栈判断函数,参数是指向操作符栈顶编号的指针
//如果为空栈返回1,否则返回0
int isEmpty(int* ptop)
{
return *ptop==-1;
}
//满栈判断函数,参数是指向操作符栈顶编号的指针
//如果为满栈返回1,否则返回0
int isFull(int* ptop)
{
return *ptop==MAXSIZE_signStack-1;
}
//报错信息函数
void Error(char *s)
{
printf("%s\n",s);
exit(1);
}
//字符栈压栈函数,共有三个参数
//第一个参数是指向栈数组第一个元素的指针
//第二个参数是要进栈的字符
//第三个参数是指向操作符栈顶编号的指针
void push_char(char *s,char item,int* ptop)
{
if (isFull(ptop))
{
Error("Stack overflow!");
}
else
{
s[++(*ptop)]=item;
}
}
//字符栈弹出函数,共有一个参数
//第一个参数是指向操作符栈顶编号的指针
void pop_char(int* ptop)
{
if(isEmpty(ptop))
{
Error("Stack Empty!");
}
else
{
--(*ptop);
}
}
//优先级判断函数,参数是被比较的字符
int grade(char a)
{
switch(a)
{
case '#':return 0;
case '(':return 1;
case '+':
case '-':return 2;
case '*':
case '/':return 3;
}
return -1;
}
三、反波兰表达式的计算方法
1.设定待计算的整数栈;
2.从左到右遍历后缀表达式的每个整数和运算符;
3.若当前字符是数字,则将连续的数字字符用sscanf函数压入真数栈,并且在之后遍历时,跳过这些字符;
4.若当前字符为运算符,则取整数栈最顶上的整数和次顶上的整数进行计算,并将这两者弹出栈,然后将计算结果压入栈中;(注意,若操作符为减号,则应该用次顶上的数字减去最顶上的数字;若操作符为除号,也同样处理)
5.最后栈中只剩下了一个整数,这个整数就是反波兰表达式计算的最终结果。
四、反波兰表达式的计算·示例代码
#include
#include
#define MAXSIZE_numStack 100
#define MAXSIZE_expression 1000
int numStack[MAXSIZE_numStack]; //后缀计算数字栈
int numtop; //后缀计算数字栈栈顶编号
//后缀表达式计算函数及其附属函数的声明
int anti_poland_cal(char* expression);
void initStack(int* ptop);
int isEmpty(int* ptop);
int isFull1(int* ptop);
void Error(char *s);
void push_int(int *s,int item,int* ptop);
void pop_int(int* ptop);
char expression[MAXSIZE_expression];//待计算后缀表达式
int main(void)
{
gets(expression);
printf("%d",anti_poland_cal(expression));
return 0;
}
//后缀表达式计算函数
int anti_poland_cal(char* expression)
{
//设定计算数字栈
initStack(&numtop);
//遍历中缀表达式
int i;
int tmp;
//tmp用于存储读取的数字
for (i=0;i='0'&&expression[i]<='9')
{
sscanf(expression+i,"%d",&tmp);
push_int(numStack,tmp,&numtop);
while (expression[i]>='0'&&expression[i]<='9')
{
i++;
}
i--;
//因为每一轮for循环都会自动对i进行累加,所以要i--
}
else if (expression[i]=='+')
{
int tmp1,tmp2,result;
//tmp1和tmp2分别用于存储栈顶和次顶的元素,result用于得出计算结果
tmp1=numStack[numtop];
pop_int(&numtop);
//取值后,直接弹出
tmp2=numStack[numtop];
pop_int(&numtop);
result=tmp1+tmp2;
push_int(numStack,result,&numtop);
//计算结果压入栈
}
else if (expression[i]=='-')
{
int tmp1,tmp2,result;
tmp1=numStack[numtop];
pop_int(&numtop);
tmp2=numStack[numtop];
pop_int(&numtop);
result=tmp2-tmp1;
push_int(numStack,result,&numtop);
}
else if (expression[i]=='*')
{
int tmp1,tmp2,result;
tmp1=numStack[numtop];
pop_int(&numtop);
tmp2=numStack[numtop];
pop_int(&numtop);
result=tmp2*tmp1;
push_int(numStack,result,&numtop);
}
else if (expression[i]=='/')
{
int tmp1,tmp2,result;
tmp1=numStack[numtop];
pop_int(&numtop);
tmp2=numStack[numtop];
pop_int(&numtop);
result=tmp2/tmp1;
push_int(numStack,result,&numtop);
}
}
return numStack[0];
}
//建栈函数,参数是指向操作符栈顶编号的指针
void initStack(int* ptop)
{
*ptop=-1;
}
//空栈判断函数,参数是指向操作符栈顶编号的指针
//如果为空栈返回1,否则返回0
int isEmpty(int* ptop)
{
return *ptop==-1;
}
//满栈判断函数,参数是指向操作符栈顶编号的指针
//如果为满栈返回1,否则返回0
int isFull1(int* ptop)
{
return *ptop==MAXSIZE_numStack-1;
}
//报错信息函数
void Error(char *s)
{
printf("%s\n",s);
exit(1);
}
//整数型压栈函数,共有三个参数
//第一个参数是指向栈数组第一个元素的指针
//第二个参数是要进栈的整数
//第三个参数是指向操作符栈顶编号的指针
void push_int(int *s,int item,int* ptop)
{
if (isFull1(ptop))
{
Error("Stack overflow!");
}
else
{
s[++(*ptop)]=item;
}
}
//整数型栈弹出函数,共有一个参数
//第一个参数是指向操作符栈顶编号的指针
void pop_int(int* ptop)
{
if(isEmpty(ptop))
{
Error("Stack Empty!");
}
else
{
--(*ptop);
}
}
五、特别提醒
请来自航专的同学不要直接复制代码,会查重的!