//中缀表达式转后缀表达式
void Mid_To_Ni(char str,int length,Stack res)
str:中缀表达式
length:中缀表达式长度
res:后缀表达式
//根据后缀表达式计算
char compute(Stack s)
s:后缀表达式
return:计算结果
//用栈实现中缀表达式转后缀表达式
#include <stdio.h>
#include <stdlib.h>
//代码中函数返回值:1表示true,0表示false
#define MaxSize 20 //栈最多可以放几个
typedef struct Stack{
char str[MaxSize]; //栈顺序表
int top; //栈顶指针
}Stack;
void InitStack(Stack *S){
S->top=-1; //栈顶指针初始化为-1
}
//入栈
int Push(Stack *S,char c){ //进栈函数
if(S->top>=MaxSize)
return 0;
S->top++;
S->str[S->top]=c;
//printf("%c",S->str[S->top]);
//show(*S);
return 1;
}
//获得栈顶元素
int GetTop(Stack s , char *c){
if(s.top<0){
return 0;
}
(*c)=s.str[s.top];
return 1;
}
//出栈
int Pop(Stack *S,char *c){
if(S->top<0)
return 0;
(*c)=S->str[S->top]; //这里要*c,因为传入的是引用变量
S->top--;
return 1;
}
//判断栈是否为空
int IsEmptyStack(Stack s){
if(s.top==-1){
return 1;
}
return 0;
}
//打印一下栈
void show(Stack S){
//printf("%d",S.top);
printf("当前栈内元素为:");
for(int i=0;i<=S.top;i++){ //这里是要<=S.top;因为top是指向栈顶元素,从-1开始的;
printf("%c\t",S.str[i]);
}
printf("\n");
}
//中缀表达式转后缀表达式
void Mid_To_Ni(char *str,int length,Stack* res){
Stack s; //定义一个栈
InitStack(&s); //初始化
char chr[length]; //存储后缀表达式
int chr_pos = 0; //后缀表达式的指针
for(int i=0;i<length;i++){
printf("%c",str[i]);
}
printf("\n");
for(int i=0;i<length;i++){ //遍历输入的算式
//遇到界限符
if(str[i]=='('||str[i]==')'){
if(str[i]=='('){ //如果是(直接入栈
Push(&s,str[i]);
}else{ //遇到),则依次弹出栈内运算符并加入后缀表达式
char c;
Pop(&s,&c);
while(c!='('){ //直到弹出(为止
chr[chr_pos++]=c;
Pop(&s,&c);
}
}
}
else if(str[i]=='+'||str[i]=='-'||str[i]=='*'||str[i]=='/'){
//如果遇到运算符,依次弹出栈内优先级高于或等于当前运算符的所有运算符,并加入后缀表达式
//若碰到(或栈空则停止,之后再把当前运算符进栈
if(str[i]=='*'||str[i]=='/'){ //遇到乘除,高于或等于乘除的运算符是*/
char c;GetTop(s,&c);
while(GetTop(s,&c)!=0&&c!='('){ //碰到(或栈空则停止
if(c=='*'||c=='/'){ //高于或等于乘除的运算符是*/
Pop(&s,&c);
chr[chr_pos++]=c; //加入后缀表达式
}else{
break;
}
}
Push(&s,str[i]); //再把当前运算符进栈
}else{
char c;GetTop(s,&c);
while(GetTop(s,&c)!=0&&c!='('){
Pop(&s,&c);
chr[chr_pos++]=c;
}
Push(&s,str[i]);
}
}else{
//遇到操作数,直接加入后缀表达式
chr[chr_pos++]=str[i];
}
show(s);
}
//将栈中剩余运算符依次弹出,并加入后缀表达式
char c;
while(IsEmptyStack(s)!=1){
Pop(&s,&c);
chr[chr_pos++]=c;
}
//打印后缀表达式,并将后缀表达式压入一个栈
for(int i=0;i<chr_pos;i++){
Push(res,chr[i]);
}
return chr_pos; //返回后缀表达式长度
}
//根据后缀表达式计算
char compute(Stack s){
Stack stack; //定义一个操作数栈,用于存放操作数
InitStack(&stack);
for(int i=0;i<=s.top;i++){ //遍历后缀表达式,因为栈的指针是指向栈顶元素所以一定要是<=!!!!!!!!!!
if(s.str[i]!='+'&&s.str[i]!='-'&&s.str[i]!='*'&&s.str[i]!='/'){ //如果遇到操作数,无脑入栈
Push(&stack,s.str[i]);
}else{ //如果是操作符,则弹出操作数栈栈顶的两个元素
char c;
Pop(&stack,&c);
int b = c-'0'; //-'0'是将其转化为整数 //栈顶元素
Pop(&stack,&c);
int a = c-'0'; //-'0'是将其转化为整数 //次栈顶元素,一定要注意顺序!!!!!
switch(s.str[i]){
case '+': Push(&stack,(char)a+b+'0'); break; //+'0'是将其转化为字符
case '-': Push(&stack,(char)a-b+'0'); break;
case '*': Push(&stack,(char)a*b+'0'); break;
case '/': Push(&stack,(char)a/b+'0'); break;
}
}
show(stack); //打印操作数栈
}
return stack.str[stack.top]; //返回计算结果
}
int main()
{
//char s[11]={'a','+','b','-','(','c','+','d',')','*','m'};
char s[13]={'7','-','2','*','(','1','+','1',')','-','6','/','3'};
char chr[13];
//存储压入栈中的后缀表达式
Stack stack;
InitStack(&stack);
//中缀转后缀
Mid_To_Ni(s,13,&stack);
//打印压入栈中的后缀表达式
for(int i=0;i<=stack.top;i++){
printf("%c",stack.str[i]);
}
printf("\n");
printf("\n计算结果为:%c",compute(stack));
return 0;
}