栈学习中必做题--中缀表达式转换成后缀表达式(后缀表达式也叫逆波兰表达式)
列如(a+b)--ab+
首先用顺序存储来实现:
#include<stdio.h>
#include<stdlib.h>
char stack[100]={'\0'};
int compare(char s1,char s2);
int isblock();
void pop(int t);
void push(char s,int i);
int isnum(char s);
int main()
{
char str[100]={'\0'};
int i,t=0;
gets(str);
for(i=0;str[i]!='\0';i++)
{
if(isnum(str[i])) printf("%c",str[i]);
else
{
if(isblock()) push(str[i],0);
else if(compare(stack[t],str[i])==1) push(str[i],++t);
else if(compare(stack[t],str[i])==2)
{
for(;compare(stack[t],str[i])==2;t--)
{
printf("%c",stack[t]);
pop(t);
}
push(str[i],++t);
}
else if(compare(stack[t],str[i])==0)
{
for(;stack[t]!='(';t--)
{
printf("%c",stack[t]);
pop(t);//这里加不加这句都可以,按照逻辑加上为好
}
pop(t--);
}
}
}
if(t>=0)
{
for(;t>=0;t--)
printf("%c",stack[t]);
}
return 0;
}
int isnum(char s)
{
if(s=='a'||s=='b'||s=='c')
return 1;
else return 0;
}
void push(char s,int i)
{
stack[i]=s;
}
void pop(int t)
{
stack[t]='\0';
}
int isblock()
{
if(stack[0]=='\0')
return 1;
else return 0;
}
int compare(char s1,char s2)
{
if((s1=='+'||s1=='-')&&(s2=='*'||s2=='/')) return 1;
else if((s1=='*'||s1=='/')&&(s2=='*'||s2=='/')) return 2;
else if((s1=='+'||s1=='-')&&(s2=='+'||s2=='-')) return 2;
else if((s1=='*'||s1=='/')&&(s2=='+'||s2=='-')) return 2;
else if (s2=='('||s1=='(') return 1;
else if(s2==')') return 0;
}
用教科书般的栈来实现中缀到后缀
#define STACKSIZE 20
typedef struct
{
char *top;
char *base;
int stacksize;
}sqstack;
void initstack(sqstack *s)
{
s->base=(char *)malloc(STACKSIZE*sizeof(char));
if(!s->base)
exit(0);
s->top=s->base;
s->stacksize=STACKSIZE;
}
void push(sqstack *s,char e)
{
if(s->top-s->base>=s->stacksize)
{
s->base=(char *)realloc(s->stacksize,(s->stacksize+STACKSIZE)*sizeof(char));
if(!s->base)
exit(0);
}
*(s->top)=e;
s->top++;
}
void pop(sqstack *s,char *e)
{
if(s->base==s->top)
{
exit(0);
}
s->top--;
*e=*(s->top);
}
int stacklen(sqstack s)
{
return (s.top-s.base);
}
int main()
{
sqstack s;
initstack(&s);
char c,e;
printf("请输入中缀表达式\n");
scanf("%c",&c);
while(c!='\n')
{
while(c>='0'&&c<='9')//关键的地方,为了防止输入两位数以上的数字导致的错误
{
printf("%c",c);
scanf("%c",&c);
if(c<'0'||c>'9')
{
printf(" ");
}
}
if(')'==c)//右括号,弹出元素,弹到左括号为止
{
pop(&s,&e);
while(e!='(')
{
printf("%c ",e);
pop(&s,&e);
}
}
else if(c=='+'||c=='-')//+和-的优先级最低,只要是这两个,栈在非空时就要一直弹元素出来,弹到出现括号和空栈 {
if(!stacklen(s))
{
push(&s,c);
}
else
{
do
{
pop(&s,&e);
if('('==e)
{
push(&s,e);
}
else
{
printf("%c ",e);
}
}while(stacklen(s)&&'('!=e);
push(&s,c);//不要忘记要把输入的元素压栈
}
}
else if(c=='*'||c=='/'||c=='(')//优先级最高,必修压栈
{
push(&s,c);
}
else if(c=='\n')
{
break;
}
else
{
printf("输入有误");
return -1;
}
scanf("%c",&c);
}
while(stacklen(s))//栈不为空时
{
pop(&s,&e);
printf("%c ",e);
}
return 0;
}逆波兰计算器:
列如:输入:9 3 1 - 3 * + 10 2 / +
输出为:20
#define STACKSIZE 20
#include<ctype.h>
typedef struct
{
double *top;
double *base;
int stacksize;
}sqstack;
void initstack(sqstack *s)
{
s->base=(double *)malloc(STACKSIZE*sizeof(double));
if(!s->base)
exit(0);
s->top=s->base;
s->stacksize=STACKSIZE;
}
void push(sqstack *s,double e)
{
if(s->top-s->base>=s->stacksize)
{
s->base=(double *)realloc(s->stacksize,(s->stacksize+STACKSIZE)*sizeof(double));
if(!s->base)
exit(0);
}
*(s->top)=e;
s->top++;
}
void pop(sqstack *s,double *e)
{
if(s->base==s->top)
{
exit(0);
}
s->top--;
*e=*(s->top);
}
int stacklen(sqstack s)
{
return (s.top-s.base);
}
int main()
{
sqstack s;
initstack(&s);
char c;
int i=0;
double d,e;
printf("请按逆波兰表达式计算待输入数据,数据与运算符之间用空格隔开,以#结束\n");
scanf("%c",&c);
char str[100];
while(c!='#')
{
while(isdigit(c) ||c=='.')//用于过滤数字
{
str[i++]=c;
str[i]='\0';// 必须加上;
if(i>=10)
{
printf("数据过大");
return -1;
}
scanf("%c",&c);
if(c==' ')
{
d=atof(str);//转换为浮点数--atod转换为整形
push(&s,d);
i=0;
break;
}
}
switch(c)
{
case'+':
pop(&s,&e);
pop(&s,&d);
push(&s,d + e);
break;
case'-':
pop(&s,&e);
pop(&s,&d);
push(&s,d-e);
break;
case'*':
pop(&s,&e);
pop(&s,&d);
push(&s,d * e);
break;
case'/':
pop(&s,&e);
pop(&s,&d);
if(e!=0)
{
push(&s,d / e);
}
else
{
printf("除数为0,有错");
return -1;
}
break;
}
scanf("%c",&c);
}
pop(&s,&d);
printf("结果为:%lf\n",d);
return 0;
}
本文介绍如何将中缀表达式转换为后缀表达式(逆波兰表达式),并实现逆波兰计算器。通过两种不同的栈实现方式,详细展示了算法流程与核心代码。
714

被折叠的 条评论
为什么被折叠?



