#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#define Min 1e-8
#define maxSize 10
int priority(char p){
if(p=='+'||p=='-'){
return 0;
}else{
return 1;
}
}
//子表达的计算
int calSub(float opand1,char op,float opand2,float &result){
//根据操作符进行计算
if(op == '*') result=opand1*opand2;
if(op == '+') result=opand1+opand2;
if(op == '-') result=opand1-opand2;
if(op == '/'){//若是除则需要判断除数为零的情况
if(fabs(opand2)<Min){// 浮点数没有准确的表达,只能用绝对值来表示差不多的范围
return 0;
}
else{
result =opand1/opand2;
}
}
return 1;
}
int calStackTopTwo(float s1[],int &top1,char s2[],int &top2){
float a=s1[top1--];//弹出栈顶元素后指针下移
float b=s1[top1--];
float result;
char op=s2[top2--];
int flag=calSub(b,op,a,result);//进行子表达式的计算
if(flag==0){
printf("被除数为零");
return 0;
}
s1[++top1]=result;//计算结果存入栈顶
return 1;
}
//计算表达式的函数
float getResult(char exp[]){
int i=0;//用于指向字符串(中缀表达式)的指针
//声明两个栈,一个float型,一个char型
//表达式中操作数存在一个栈内,运算符存入一个栈内
//top1,top2用于指向两个栈的栈顶
float s1[maxSize];int top1=-1;
char s2[maxSize];int top2=-1;
while(exp[i]!='\0'){//字符串结尾以'\0'
if(exp[i]>='0'&&exp[i]<='9'){//判断是否是数字,但此处只能判断0-9之间的一位数字
s1[++top1]=exp[i]-'0';//字符串转换为数字
++i;//下一个字符
}
else if(exp[i]=='(') {//如果是左括号的话直接进栈
s2[++top2]='(';
i++;
}else if(exp[i]=='*'|| //如果是运算符则进行以下判断
exp[i]=='/'||
exp[i]=='+'||
exp[i]=='-'){
//如果栈顶为左括号或者栈空,或者当前符号优先级大于栈顶符号优先级则入栈
if(s2[top2]=='('||top2==-1||priority(exp[i])>priority(s2[top2])){
s2[++top2]=exp[i];
i++;
}else{
int flag=calStackTopTwo(s1,top1,s2,top2);//当前运算符小于栈顶元素优先级则弹出数据栈的两个
if(flag==0){
return 0;
}
} //操作数,进行运算后存入栈顶,完毕后i的值不发生
} //变化
else if(exp[i]==')'){//如果碰到右括号,则弹出栈内直至左括号的所有运算符
while(s2[top2]!='('){//弹出一个运算符都需要进行计算
int flag=calStackTopTwo(s1,top1,s2,top2);
if(flag==0){
return 0;
}
}
--top2;//更新栈顶指针
i++;
}
}
//当表达式进栈完毕后
//只要符号栈内还有元素就继续进行运算
while(top2!=-1){
int flag=calStackTopTwo(s1,top1,s2,top2);
if(flag==0){
return 0;
}
}
return s1[top1];
}
//后缀表达式计算
float calPostFix(char exp[]){
float s1[maxSize];
int top=-1;
int i=0;
while(exp[i]!='\0'){
if(exp[i]>='0'&&exp[i]<='9'){
s1[++top]=exp[i]-'0';
}else{
float a,b,result;
a=s1[top--];
b=s1[top--];//出栈顶的两个元素
int flag=calSub(a,exp[i],b,result);//子表达式计算结果存入result
if(flag==0){
printf("Error");
return 0;
}
s1[++top]=result;//将结果存入栈顶
}
i++;
}
return s1[top];
}
float calPreFix(char exp[],int length){
float s1[maxSize];
int top=-1;
for(int i=length-1;i>=0;--i){
if(exp[i] >= '0' && exp[i]<='9'){
//printf("%c",exp[i]);
s1[++top]=exp[i]-'0';
}else
{
float a,b,result;
a=s1[top--];
b=s1[top--];//出栈顶的两个元素
// printf("%f %f",s1[0],s1[1]);
int flag=calSub(a,exp[i],b,result);//子表达式计算结果存入result
if(flag==0){
printf("Error");
return 0;
}
s1[++top]=result;//将结果存入栈顶
}
}
return s1[top];
}
//中缀式转后缀式
//参数top传引用型是为了能够查看栈的最大用量
//参数s2[]数组是存储结果表达式
void infixtoPostFix(char infix[],char s2[],int &top2){
char s1[maxSize];//辅助栈
int i=0,top1=-1;
while(infix[i]!='\0'){
if(infix[i]<='9'&&infix[i]>='0'){
s2[++top2]=infix[i];
i++;
}else if(infix[i]=='('){
s1[++top1]=infix[i];
i++;
}else if(infix[i]=='*'||infix[i]=='+'||infix[i]=='-'||infix[i]=='/'){
if(top1==-1||s1[top1]=='('||priority(infix[i])>priority(s1[top1])){
//中缀转后缀,当前运算符优先级小于等于栈顶运算符优先级则出栈
s1[++top1]=infix[i];
i++;
}else{
s2[++top2]=s1[top1--];
}
}else if(infix[i]==')'){
while(s1[top1]!='('){
s2[++top2]=s1[top1--];
}
--top1;//
i++;
}
}
while(top1!=-1){
s2[++top2]=s1[top1--];
}
}
//中缀式转前缀式
void infixtoPreFix(char infix[],int length,char s3[],int &top2){
char s1[maxSize];//辅助栈
char s2[maxSize];//
int i=length-1,top1=-1;
while(i>=0){
if(infix[i]<='9'&&infix[i]>='0'){
s2[++top2]=infix[i];
i--;
}else if(infix[i]==')'){
s1[++top1]=infix[i];
i--;
}else if(infix[i]=='*'||infix[i]=='+'||infix[i]=='-'||infix[i]=='/'){
//中缀转前缀,当前运算符优先级小于栈顶运算符优先级则出栈
if(top1==-1||s1[top1]==')'||priority(infix[i]) >= priority(s1[top1])){
s1[++top1]=infix[i];
i--;
}else{
s2[++top2]=s1[top1--];
}
}else if(infix[i]=='('){
while(s1[top1]!=')'){
s2[++top2]=s1[top1--];
}
--top1;
i--;
}
}
while(top1!= -1){
s2[++top2]=s1[top1--];
}
int v=0;
for(int i=top2;i>=0;i--){
s3[v++]=s2[i];
}
}
int getlength(char s[]){
int length=0;
for(int i=0;i<maxSize;i++){
if((s[i]<'9'&&s[i]>'0')||s[i]=='+'||s[i]=='*'||
s[i]=='/'||s[i]=='-'||s[i]=='('||s[i]==')'){
length++;
}
}
return length;
}
int main(){
char s[maxSize];
printf("请输入中缀表达式:\n");
scanf("%s",s);//录入字符串
printf("%s=%f\n",s,getResult(s));
char result[maxSize];//存放转换后结果
int top1=-1;
infixtoPostFix(s,result,top1);
printf("中缀转后缀为:%s\n",result);
printf("后缀的结果表达式为:%f\n",calPostFix(result));
int top2=-1;
char result1[maxSize];//存放转换后结果
infixtoPreFix(s,getlength(s),result1,top2);
printf("中缀转前缀为:%s\n",result1);
printf("前缀的结果表达式为:%f\n",calPreFix(result1,getlength(s)));
}
代码运行截图:
其中在转化时需要注意: