栈学习中必做题--中缀表达式转换成后缀表达式(后缀表达式也叫逆波兰表达式)
列如(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; }