#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
//附加功能:
//附加功能1:附加了%取余数的操作!!!
//附加功能2:附加了求对数ln的功能!!!
//附加功能3:附加了取绝对值操作!!!
//别忘了写程序之前写个伪代码分析一下!!!
//别靠空想!!!及其浪费时间!!!多谢谢伪代码分析一下!!!
//后缀表示法计算时候的思路!!!先把元素推到栈中,每碰到一个
char stack[50];//用于存储outpush中的元素
char output[50];//用于存储中缀表达式结果
char nouse[50];//用于存储’)’这个不在中缀表达式中出现的元素
int flag=0;//标志量,标定限制状态
char sz[50];//存储中缀表达式中的数据
char laji[50];//垃圾桶,存取无用的字符元素
int szz[50];//存储中缀表达式中的数字,以及中缀表达式中的符号,在szz中分别用80001,80002,80003,80004,80005表示 ’+’ ’-‘ ‘*’ ‘/’ ’%’
int jieguo[50];//中缀表达式求值中的堆栈
int wuyong[50];//垃圾桶,用于存储栈操作中无用的数字
int laji1[50];//垃圾桶
int ce[3]= {1,2,-9999};
int ce1[3]= {7,8,-9999};
void push(char stack3[],char push1);//压栈操作
int change(char aa);//将输入的字符串的每个字母依次压栈,求中缀表达式
void pop(char stack1[],char stack2[]);//从第一个栈弹出给第二个,必须堆栈中用东西才可以弹出
void push1(int stack31[],int push11);//在计算中缀表达式中用于压栈
void pop1(int stack11[],int stack21[]);//在中缀表达式求值时用于弹栈
void WritetoFile(char wenjian[]); //用于将中缀表达式写入文件
void ReadfromFile(char wenjian1[]); //用于将中缀表达式从文件中读出
void pop(char stack1[],char stack2[])
{
int i;
int j;
char tmppop;
for(i=0; i<50; i++)
{
if(stack1[i]=='\0')
{
tmppop=stack1[0];
for(j=0; j<i; j++)
{
stack1[j]=stack1[j+1];
}
break;
}
}
push(stack2,tmppop);
}
void push(char stack3[],char push1)
{
int i;
int j;
for(i=0; i<50; i++)
{
if(stack3[i]=='\0')//在函数里用函数里的变量!!!一定注意!!!小心!!!
{
if(i==0)
{
stack3[0]=push1;
}
else
{
for(j=0; j<=i; j++)
{
stack3[i-j+1]=stack3[i-j];
}
stack3[0]=push1;
break;
}
}
}
}
void push1(int stack31[],int push11)
{
int i;
int j;
for(i=0; i<50; i++)
{
if(stack31[i]<=-9999)//在函数里用函数里的变量!!!一定注意!!!小心!!!
{
if(i==0)
{
stack31[0]=push11;
}
else
{
for(j=0; j<=i; j++)
{
stack31[i-j+1]=stack31[i-j];
}
stack31[0]=push11;
break;
}
}
}
}
void pop1(int stack11[],int stack21[])//从第一个栈弹出给第二个,必须堆栈中用东西才可以弹出
{
int i;
int j;
int tmppop1;
for(i=0; i<50; i++)
{
if(stack11[i]<=-9999)
{
tmppop1=stack11[0];
if(i==0)
{
}
else
{
for(j=0; j<i; j++)
{
stack11[j]=stack11[j+1];
}
break;
}
}
}
push1(stack21,tmppop1);
}
int change(char aa)
{
int i;
int j;
if(aa=='#')
{
flag = flag + 1;
}
if(flag==0)
{
printf("还未遇到#");
}
else
{
if(flag==1)
{
switch (aa)
{
case '(':
printf("压入%c\n",aa);
push(stack,aa);
break;
case ')':
for(i=0; i<50; i++)
{
if(stack[i]=='(')
{
for(j=0; j<i; j++)
{
printf("弹出从算符堆栈到output%c\n",stack[0]);
pop(stack,output);
}
printf("弹出从算符堆栈到nouse%c\n",stack[0]);
pop(stack,nouse);
break;
}
}
break;
case '+':
if(stack[0]=='\0')
{
printf("压入%c进入算符堆栈\n",aa);
push(stack,aa);
}
else
{
if(((stack[0]=='*')||(stack[0]=='/'))&&(stack[0]!='('))
{
printf("弹出从算符堆栈到output%c\n",stack[0]);
pop(stack,output);
if((stack[0]=='+')||(stack[0]=='-'))
{
printf("弹出从算符堆栈到output%c\n",stack[0]);
pop(stack,output);
printf("压入%c进入算符堆栈\n",aa);
push(stack,aa);
}
else
{
printf("压入%c进入算符堆栈\n",aa);
push(stack,aa);
}
}
else
{
if(stack[0]=='(') //这个位置之前不小心写成了aa,碰到不会的别慌,赶紧用printf检查在哪里附近出了问题与然后细心排查错误!!!
{
printf("压入%c进入算符堆栈\n",aa);
push(stack,aa);
}
else
{
printf("弹出从算符堆栈到output%c\n",stack[0]);
pop(stack,output);
printf("压入%c进入算符堆栈\n",aa);
push(stack,aa);
}
}
}
break;
case '-':
if(stack[0]=='\0')
{
printf("压入%c进入算符堆栈\n",aa);
push(stack,aa);
}
else
{
if(((stack[0]=='*')||(stack[0]=='/'))&&(stack[0]!='(')&&(stack[0]!='%'))
{
printf("弹出从算符堆栈到output%c\n",stack[0]);
pop(stack,output);
if((stack[0]=='+')||(stack[0]=='-'))
{
printf("弹出从算符堆栈到output%c\n",stack[0]);
pop(stack,output);
printf("压入%c进入算符堆栈\n",aa);
push(stack,aa);
}
else
{
printf("压入%c进入算符堆栈\n",aa);
push(stack,aa);
}
}
else
{
if(stack[0]=='(')
{
printf("压入%c进入算符堆栈\n",aa);
push(stack,aa);
}
else
{
printf("弹出从算符堆栈到output%c\n",stack[0]);
pop(stack,output);
printf("压入%c进入算符堆栈\n",aa);
push(stack,aa);
}
}
}
break;
case '*':
if(stack[0]=='\0')
{
printf("压入%c进入算符堆栈\n",aa);
push(stack,aa);
}
else
{
if((stack[0]=='+')||(stack[0]=='-')||(stack[0]!='('))
{
printf("压入%c进入算符堆栈\n",aa);
push(stack,aa);
}
else
{
if(stack[0]!='(')
{
printf("弹出从算符堆栈到output%c\n",stack[0]);
pop(stack,output);
printf("压入%c进入算符堆栈\n",aa);
push(stack,aa);
}
else
{
printf("压入%c进入算符堆栈\n",aa);
push(stack,aa);
}
}
}
break;
case '/':
if(stack[0]=='\0')
{
printf("压入%c进入算符堆栈\n",aa);
push(stack,aa);
}
else
{
if((stack[0]=='+')||(stack[0]=='-')||(stack[0]!='('))
{
printf("压入%c进入算符堆栈\n",aa);
push(stack,aa);
}
else
{
if(stack[0]!='(')
{
printf("弹出从算符堆栈到output%c\n",stack[0]);
pop(stack,output);
printf("压入%c进入算符堆栈\n",aa);
push(stack,aa);
}
else
{
printf("压入%c进入算符堆栈\n",aa);
push(stack,aa);
}
}
}
break;
case '%':
if(stack[0]=='\0')
{
printf("压入%c进入算符堆栈\n",aa);
push(stack,aa);
}
else
{
if((stack[0]=='+')||(stack[0]=='-')||(stack[0]!='('))
{
printf("压入%c进入算符堆栈\n",aa);
push(stack,aa);
}
else
{
if(stack[0]!='(')
{
printf("弹出从算符堆栈到output%c\n",stack[0]);
pop(stack,output);
printf("压入%c进入算符堆栈\n",aa);
push(stack,aa);
}
else
{
printf("压入%c进入算符堆栈\n",aa);
push(stack,aa);
}
}
}
break;
default:
if(aa=='#')
{
;
}
else
{
printf("压入%c进入output\n",aa);
push(output,aa);
}
break;
}
}
else
{
flag=flag-2;
return 2;
}
}
}
void WritetoFile(char wenjian[])
{
FILE *fp;
int flag;
flag=1;
if((fp = fopen("zhongzhui.txt","w"))==NULL)
{
printf("写入文件失败\n");
flag=0;
}
if(flag==1)
{
printf("已经成功将中缀表达式写入文件\n");
fprintf(fp,"%50s",wenjian);
fclose(fp);
}
}
void ReadfromFile(char wenjian1[])
{
FILE *fp;
int flag;
flag=1;
if((fp=fopen("zhongzhui.txt","r"))==NULL)
{
printf("读取文件失败\n");
flag=0;
}
if(flag==1)
{
fscanf(fp,"%50s",wenjian1);
printf("读取到的中缀表达式为%s\n",wenjian1);
}
fclose(fp);
}
int main()
{
int i;
int j;
int loog;
int tmp6;
char zh[50];
char dz[50];
char fuhao[50];
int zzbsf[50];
int xunhuan;
for(xunhuan=0;xunhuan<=20;xunhuan++)
{
for(i=0; i<50; i++)
{
zzbsf[50]='\0';
stack[i]='\0';
output[i]='\0';
zh[i]='\0';
nouse[i]='\0';
dz[i]='\0';
fuhao[i]='e';
sz[i]='\0';
szz[i]=-20000;
jieguo[i]=-20000;
laji[i]=-20000;
wuyong[i]=-20000;
}
printf("请输入表达式,开始需要输入#\n");
scanf("%s",zh);
printf("\n");
strcpy(zzbsf,zh);
for(i=0; i<50; i++)
{
if(zh[i]=='\0')
{
break;
}
else
{
if(change(zh[i])==2)
{
break;
}
}
}
for(j=0; j<=50; j++)
{
if(stack[j]!='\0')
{
push(output,stack[j]);
}
else
{
break;
}
}
pop(output,nouse);
for(i=0; i<50; i++)
{
if(output[i]=='\0')
{
output[i-1]='\0';
break;
}
}
strcpy(dz,output);
for(i=0; i<50; i++)
{
if(output[i]=='\0')
{
for(j=0; j<i; j++)
{
output[i-j-1]=dz[j];
}
break;
}
}
tmp6=0;
printf("\n");
pop(zzbsf,nouse);
printf("中缀表示法为%s\n",zzbsf);
printf("\n");
printf("后缀表示法为%s\n",output);
getchar();
for(i=0; i<50; i++)
{
if(output[i]=='\0')
{
break;
}
else
{
if((output[i]!='+')&&(output[i]!='-')&&(output[i]!='*')&&(output[i]!='/')&&(output[i]!='%'))
{
printf("请输入您要输入\n");
printf("请输入字符%c对应的数值类型\n",output[i]);
printf("1.数字\n");
printf("2.ln\n");
printf("3.取绝对值\n");
scanf("%d",&loog);
getchar();
printf("请输入\n");
if(loog==1)
{
scanf("%d",&tmp6);
getchar();
szz[i]=tmp6;
}
else
{
if(loog==2)
{
scanf("%d",&tmp6);
getchar();
szz[i]=log(tmp6);
}
else
{
scanf("%d",&tmp6);
getchar();
szz[i]=abs(tmp6);
}
}
}
else
{
switch (output[i])//switch语句别忘了加大括号!!!
{
case '+':
szz[i]=80001;
break;
case '-':
szz[i]=80002;
break;
case '*':
szz[i]=80003;
break;
case '/':
szz[i]=80004;
break;
case '%':
szz[i]=80005;
break;
default:
szz[i]=-30000;
break;
}
}
}
}
for(j=0; j<50; j++)
{
if(szz[0]<=-9999)
{
break;
}
else
{
if((szz[0]==80001)||(szz[0]==80002)||(szz[0]==80003)||(szz[0]==80004)||(szz[0]==80005))
{
pop1(szz,wuyong);
switch ((int)(wuyong[0]))
{
case 80001:
printf("弹出+并进行相应计算\n");
printf("弹出%d\n",jieguo[0]);
printf("弹出%d\n",jieguo[1]);
printf("压入%d+%d=%d",jieguo[1],jieguo[0],jieguo[1]+jieguo[0]);
pop1(jieguo,wuyong);
pop1(jieguo,wuyong);
push1(jieguo,(wuyong[0]+wuyong[1]));
break;
case 80002:
printf("弹出-并进行相应计算\n");
printf("弹出%d\n",jieguo[0]);
printf("弹出%d\n",jieguo[1]);
printf("压入%d+%d=%d",jieguo[1],jieguo[0],jieguo[1]-jieguo[0]);
pop1(jieguo,wuyong);
pop1(jieguo,wuyong);
push1(jieguo,(wuyong[0]-wuyong[1]));
break;
case 80003:
printf("弹出*并进行相应计算\n");
printf("弹出%d\n",jieguo[0]);
printf("弹出%d\n",jieguo[1]);
printf("压入%d+%d=%d",jieguo[1],jieguo[0],jieguo[1]*jieguo[0]);
pop1(jieguo,wuyong);
pop1(jieguo,wuyong);
push1(jieguo,(wuyong[0]*wuyong[1]));
break;
case 80004:
printf("弹出/并进行相应计算\n");
printf("弹出%d\n",jieguo[0]);
printf("弹出%d\n",jieguo[1]);
printf("压入%d+%d=%d",jieguo[1],jieguo[0],jieguo[1]/jieguo[0]);
pop1(jieguo,wuyong);
pop1(jieguo,wuyong);
push1(jieguo,(wuyong[0]/wuyong[1]));
break;
case 80005:
printf("弹出%并进行相应计算\n");
printf("弹出%d\n",jieguo[0]);
printf("弹出%d\n",jieguo[1]);
printf("压入%d quyu %d=%d\n",jieguo[1],jieguo[0],(int)(jieguo[1])%(int)(jieguo[0]));
pop1(jieguo,wuyong);
pop1(jieguo,wuyong);
push1(jieguo,(wuyong[0]%wuyong[1]));
break;
}
}
else
{
printf("压入数字%d\n",szz[0]);
pop1(szz,jieguo);
}
}
}
printf("中缀表达式的计算结果为%d\n",jieguo[0]);
printf("如果想读入文件请输入1,否则请输入2\n");
scanf("%d",&j);
if(j==1)
{
WritetoFile(output);
}
else
{
;
}
printf("如果想读取文件并显示请输入1,否则请输入2\n");
scanf("%d",&j);
if(j==1)
{
ReadfromFile(output) ;
}
else
{
;
}
}
return 0;
}
c语言中缀表达式转化后缀表达式优化final
最新推荐文章于 2022-08-30 00:26:42 发布
本文详细介绍了如何使用C语言将中缀表达式转换为后缀表达式(也称为逆波兰表示法),并讨论了算法优化的最终版本。通过对表达式的操作,利用栈数据结构,实现了括号匹配和运算符优先级的处理,提高了计算效率。
摘要由CSDN通过智能技术生成