因为数据结构老师布置了栈的后缀表达式实验,经过思考,有以下反思。
中缀表达式转换为后缀表达式
后缀表达式的计算:
后缀表达式的计算,只需要从左到右,遇到运算符就计算即可,无需考虑优先级的问题
代码块如下
#include
#include
#include
typedef struct node{
int data;
struct node *next;
}node,*link;
typedef struct snode
{
char c;
struct snode *next;
}snode,*slink;
void dealExpression();
char opTop(slink &s);
void push(link &s,int x);
void push1(slink &s,char x);
int pop1(slink &s);
int pop(link &s);
void calculate(link &s,slink &s1);
int main(void)
{
dealExpression();
}
void empty(link &s)
{
s=NULL;
}
void empty1(slink &s)
{
s=NULL;
}
void push(link &s,int x)
{ node *p=(link )malloc(sizeof(node));
p->data=x;
p->next=s;
s=p;
}
void push1(slink &s,char x)
{ snode *p=(slink )malloc(sizeof(snode));
p->c=x;
p->next=s;
s=p;
}
int pop(link &s)
{
int x;
if(s==NULL){
printf("it is an empty stack");
}
else{
x=s->data;
s=s->next;
return x;
}
}
int pop1(slink &s)
{
snode *p=s;
char x;
if(s==NULL){
printf("it is an empty stack");
}
else{
x=p->c;
s=s->next;
free(p);
return x;
}
}
char opTop(slink &s1){
if(s1==NULL){
return 0;
}
else{
return s1->c;
}
}
//计算,将栈中的数值和运算符进行计算
void calculate(link &s,slink &s1)
{
int number1,number2;
char opf;
number1=pop(s);
number2=pop(s);
opf=pop1(s1);
int tmpResult=0;
switch(opf){
case '+':
tmpResult=number1+number2;
break;
case '-':
tmpResult=number2-number1;
break;
case '*':
tmpResult=number2*number1;
break;
case '/':
tmpResult=number2/number1;
break;
}
push(s,tmpResult);
}
//将中缀表达式转化为后缀,并且存储在数值中
void dealExpression()
{
char change[100];
int i=0;
char a,b;
node *s;
snode *s1;
//定义节点一定要初始化节点,要不然会发生分配内存错误
empty(s);
empty1(s1);
char currentchar;
scanf("%c",¤tchar);
// 转换过程
while(currentchar!='='){
switch(currentchar){
case '+':
case '-':
if(opTop(s1)==0){
push1(s1,currentchar);
}
else{
while(opTop(s1)=='+'||opTop(s1)=='-'||opTop(s1)=='*'||opTop(s1)=='/')
{
a=pop1(s1);
change[i]=a;
i++;
printf("%c",a);
}
push1(s1,currentchar);
}
scanf("%c",¤tchar);
break;
case '*':
case '/':
if(opTop(s1)==NULL){
push1(s1,currentchar);
}
else{
while(opTop(s1)=='*'||opTop(s1)=='/')
{
a=pop1(s1);
change[i]=a;
i++;
printf("%c",a);
}
push1(s1,currentchar);
}
scanf("%c",¤tchar);
break;
case '(':
push1(s1,currentchar);
scanf("%c",¤tchar);
break;
case ')':
while(opTop(s1)!='('){
b=pop1(s1);
change[i]=b;
i++;
printf("%c",b);
}
pop1(s1);
scanf("%c",¤tchar);
break;
default:
int opNum=0;
while(currentchar>='0'¤tchar<='9'){
// 通过递归实现二位到以上的数
opNum=opNum*10+currentchar-'0';
scanf("%c",¤tchar);
}
change[i]=char(opNum);
i++;
printf("%d",opNum);
break;
}
}
while(opTop(s1)!=0)
{
a=pop1(s1);
change[i]=char(a);
i++;
printf("%c",a);
}
// 将转化的后缀表达式进行计算,如果遇到操作符,直接计算就可,无需考虑优先级,只需要考虑到从左至右的顺序
int j=0;
while(j
遇到的问题和反思:
解决了上次中缀表达式中,地址分配错误的问题,因为上次中缀表达式,我没有将栈初始化,所以导致了地址分配错误,所以将栈初始化是很重要的。
然后遇到了case,break的问题,我大意忘记写了break,结果导致了我调试了很久才发现问题:问题是这样的,我输入的 1+2= 结果却是45,在调试中发现“+”的ASCLL码正好是43,而且在最后一次case循环中,不仅是符号栈有输入,数字栈也有输入。才发现是忘记写break,导致最后一次循环:符号栈和数字栈都有输入,符号栈的输入是“+”,数字栈的输入是“43”.所以导致最后结果是45.