栈的应用:中缀表达式计算 中缀表达式转后缀表达式(逆波兰式)中缀表达式转前缀表达式(波兰式) 后缀表达式计算 前缀表达式计算(c语言)

#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)));
	
}

代码运行截图:

其中在转化时需要注意:

发布了90 篇原创文章 · 获赞 36 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/weixin_37716512/article/details/104093043