数据结构 C 代码:表达式求值

表达式求值

用C语言实现表达式求值算法。要求从键盘输入任意的包含加减乘除的算术四则运算表达式,都能求值。操作数类型可以设定为double。

1 设置运算符栈和运算数栈辅助分析算符优先关系。
2 在读入表达式的字符序列的同时,完成运算符和运算数(整数)的识别处理,以及相应的运算。
3 在识别出运算数的同时,要将其字符序列形式转换成整数形式。
4 在程序的适当位置输出运算符栈、运算数栈、输入字符和主要操作的内容。
代码实现

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#define MAX_SIZE 1000

/*定义一个运算符栈*/
typedef struct {
	char Operator[MAX_SIZE];
	int top;
} OptorStack;
/*定义一个操作数栈*/
typedef struct {
	double Operand[MAX_SIZE];
	int top;
} OpndStack;
/*初始化运算符栈*/
void InitOptor(OptorStack *S) {
	S->top = -1;
}
/*初始化操作数栈*/
void InitOpnd(OpndStack *S) {
	S->top = -1;
}
/*运算符出栈*/
int PopOptor(OptorStack *S) {
	if(S->top==-1) {
		printf("运算符栈为空\n");
		exit(10);
	}
	S->top--;
	return 1;
}
/*操作数出栈*/
int PopOpnd(OpndStack *S) {
	if(S->top==-1) {
		printf("操作数栈为空\n");
		exit(11);
	}
	S->top--;
	return 1;
}

/*运算符入栈*/
int PushOptor(OptorStack *S,char ch) {
	if(S->top==MAX_SIZE-1) {
		printf("运算符栈满\n");
		exit(12);
	}
	S->top++;
	S->Operator[S->top]=ch;
	return 1;
}
/*操作数入栈*/
int PushOpnd(OpndStack *S,double ch) {
	if(S->top==MAX_SIZE-1) {
		printf("操作数栈满\n");
		exit(13);
	}
	S->top++;
	S->Operand[S->top]=ch;
	return 1;
}
/*取运算符栈栈顶元素*/
char GetOptor(OptorStack *S) {
	if(S->top==-1) {
		printf("运算符栈为空\n");
		exit(17);
	}
	return S->Operator[S->top];
}
/*取操作数栈栈顶元素*/
double GetOpnd(OpndStack *S) {
	if(S->top==-1) {
		printf("操作数栈为空\n");
		exit(18);
	}
	return S->Operand[S->top];
}
/*表达式运算函数*/
double Calculate(double a,double b,char op) {
	double result;
	if(op=='+') result=a+b;
	if(op=='-') result=a-b;
	if(op=='*') result=a*b;
	if(op=='/') {   //要防止除数为0
		if(b==0) {
			printf("ERROR:除数不能为0\n");
			exit(15);
		}
		result=a/b;
	}
	return result;    //返回结果result
}

int change(char ch) {
	switch(ch) {
		case '+':
			return 0;
		case '-':
			return 1;
		case '*':
			return 2;
		case '/':
			return 3;
		case '(':
			return 4;
		case ')':
			return 5;
		case '#':
			return 6;
	}
}
/*定义一个算符优先关系矩阵*/
char cmp[7][8]= {">><<<>>",">><<<>>",">>>><>>",">>>><>>","<<<<<=?",">>>>?>>","<<<<<?="};
/*算符比较函数,返回优先级:>或<或=*/
int Compare(char ch1,char ch2) {
	if(cmp[change(ch1)][change(ch2)]=='?') {
		printf("输入表达式错误");
		exit(16);
	}
	return cmp[change(ch1)][change(ch2)];
}
/*检查函数,用来检查输入的表达式的操作数和运算符的合法性*/
int Check(char *S,int len) {
	int i;
	for(i=0; i<len; i++) {
		if(S[i]>='0'&&S[i]<='9')continue;
		if(S[i]=='('||S[i]==')'||S[i]=='*'||S[i]=='/'||S[i]=='+'||S[i]=='-'||S[i]=='.')continue;
		return 0;
	}
	return 1;
}

int main() {
	char expre[9999],opd[9999];   //expre用来存储表达式,opd用来存操作数
	int len;
	OptorStack Optor;
	OpndStack Opnd;
	InitOptor(&Optor);
	InitOpnd(&Opnd);
	PushOptor(&Optor,'#');
	printf("请输入表达式:\n");
	scanf("%s",expre);
	len = strlen(expre);
	if (Check(expre,len) == 0) {
		printf("输入的表达式不合法,可能存在多余字符\n");
		exit(19);
	}
	int i,j=0,k=0;
	double x,y;
	expre[len] = '#';   //在expre数组后加个#结尾标志
	for (i=0; i<=len; i++) {
		if ((expre[i]>='0' && expre[i]<='9') || expre[i] == '.') {
			opd[k++] = expre[i];   //将数字字符存入操作数数组opd中
			j = 1;
			continue;
		}
		if(j) {
			opd[k] = '\0';
			PushOpnd(&Opnd,atof(opd));
			j=0;
			k=0;
		}
		switch (Compare(GetOptor(&Optor),expre[i])) {  //比较运算符栈的栈顶运算符和运算符expre[i]的优先级
			case '<':
				PushOptor(&Optor,expre[i]);
				break;
			case '=':
				PopOptor(&Optor);
				break;
			case '>':
				y = GetOpnd(&Opnd),PopOpnd(&Opnd);
				x = GetOpnd(&Opnd),PopOpnd(&Opnd);
				PushOpnd(&Opnd,Calculate(x,y,GetOptor(&Optor)));
				PopOptor(&Optor);
				i--;
				break;
		}
	}
	double final_result = GetOpnd(&Opnd);
	printf("该表达式的结果为:%.2lf",final_result);
	return 0;
}

Dev测试结果
请添加图片描述
请添加图片描述
请添加图片描述

  • 13
    点赞
  • 81
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值