用栈对算术表达式求值

52 篇文章 2 订阅

    假设算术表达式只包含"+"、“-”、“*”、“/”、正整数和括号的合法数学表达式。求算术表达式值的过程是:先将算术表达式转换成后缀表达式(逆波兰式),然后对该后缀表达式求值。
  1)将算术表达式exp转换成后缀表达式postexp;
  2)对后缀表达式postexp求值。
  完整代码如下:

#include <stdio.h>
#include <stdlib.h>
#define MaxSize 100

//符号栈
struct{
	char data[MaxSize];
	int top;
}op;

//数值栈
struct{
	float data[MaxSize];
	int top;
}st;


//将算术表达式exp转换为后缀表达式postexp
void trans(char exp[],char postexp[]){
	char ch;
	int i=0,j=0; //i扫描exp的下标,j扫描postexp的下标
	op.top=-1;
	ch=exp[i]; i++;
	while (ch != '\0')
	{
		switch(ch){
		case '(':    //左括号
			op.top++; op.data[op.top]=ch;
			break;
		case ')':   //右括号
			while(op.data[op.top]!='(')
			{
				postexp[j]=op.data[op.top]; j++;
				op.top--;
			}
			op.top--;
			break;
		case '+':   //为'+'或'-'时,其优先级不大于栈顶任何运算符的优先级,直到')'
		case '-':
			while (op.top!=-1 && op.data[op.top]!='(')
			{
				postexp[j]=op.data[op.top]; j++;
				op.top--;
			}
			op.top++; op.data[op.top]=ch;
			break;
		case '*':
		case '/':  //为'*'或'/'时,其优先级不大于栈顶为'*'或'/'的优先级,直到')'
			while(op.top!=-1 && op.data[op.top]!='('
				&& (op.data[op.top]=='*' || op.data[op.top]=='/')){
				postexp[j]=op.data[op.top]; j++;
				op.top--;
			}
			op.top++; op.data[op.top]=ch;
			break;
		case ' ': break;  //过滤空格
		default:
			while (ch>='0' && ch<='9')
			{
				postexp[j]=ch; j++;
				ch=exp[i]; i++;
			}
			i--;
			postexp[j]='#'; j++;
			//postexp[j]=' '; j++; //用空格标识一个数值串结束
			
		}
		ch=exp[i]; i++;
	}
	
	while(op.top!=-1){ //此时,exp扫描完毕,栈不空时出栈并存放到postexp中
		postexp[j]=op.data[op.top]; j++;
		op.top--;
	}
	postexp[j]='\0'; //给postexp表达式添加结束标识
	
}

//对后缀表达式postexp求值
float compvalue(char postexp[]){
	float d;
	char ch;
	int i=0;
	st.top=-1;
	ch=postexp[i]; i++;
	while (ch!='\0')
	{
		switch(ch){
		case '+': st.data[st.top-1]=st.data[st.top-1]+st.data[st.top];
			st.top--; break;
		case '-': st.data[st.top-1]=st.data[st.top-1]-st.data[st.top];
			st.top--; break;
		case '*': st.data[st.top-1]=st.data[st.top-1]*st.data[st.top];
			st.top--; break;
		case '/':
			if(st.data[st.top]!=0)
				st.data[st.top-1]=st.data[st.top-1]/st.data[st.top];
			else{
				printf("\n\t除零错误!\n");
				exit(0);
			}
			st.top--; break;
		default:
			d=0;
			while (ch>='0' && ch<='9')
			{
				d=10*d+ch-'0';
				ch=postexp[i]; i++;
			}
			st.top++;
			st.data[st.top]=d;
			
		}
		ch=postexp[i]; i++;
	}
	return st.data[st.top];
	
}

void main()
{
	char exp[20]="(56-20)/(4-2)";
	char postexp[30];
	float f=0.0;
	
	//求exp的逆波兰式,得到postexp
	trans(exp,postexp);
	//对postexp求值
	f=compvalue(postexp);

	printf("%s = %.2f\n",exp,f);

}

    用栈对表达式:(56-20)/(4-2)求值,效果如下:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

sanqima

一键三连,多多益善

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值