表达式求值【C语言实现】数据结构实验

表达式求值【C语言实现】数据结构实验
如果需要功能更完善、代码更简洁以及bug更少的代码,可以到我的小程序 航筱北同学上搜索查看。
在这里插入图片描述

实验内容

表达式计算是实现程序设计语言的基本问题之一,也是栈的应用的典型例子。设计一个程序,演示用算符优先法对算术表达式求值的过程。

实验要求

基本要求:以字符序列的形式从键盘输入语法正确的,不含变量的整型表达式。利用教科书表 3.1 给出的算符优先关系,实现对算术四则混合运算表达式的求值,并仿照教科书的例 3.1 演示在求值中运算符栈、运算数栈、输入字符和主要操作的变化过程。

实现提示

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

测试数据

在这里插入图片描述

C语言源代码

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

运行结果

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 52
    点赞
  • 286
    收藏
    觉得还不错? 一键收藏
  • 13
    评论
表达式运算中的应用主要是为了处理运算符的优先级和括号的匹配。下面是一个使用堆实现表达式运算的示例代码: ```c #include <stdio.h> #include <stdlib.h> // 定义堆结构 typedef struct { int top; // 顶指针 int *data; // 数据数组 } Stack; // 初始化堆 void initStack(Stack *stack, int size) { stack->top = -1; stack->data = (int *)malloc(size * sizeof(int)); } // 判断堆是否为空 int isEmpty(Stack *stack) { return stack->top == -1; } // 入操作 void push(Stack *stack, int value) { stack->data[++stack->top] = value; } // 出操作 int pop(Stack *stack) { return stack->data[stack->top--]; } // 获取顶元素 int top(Stack *stack) { return stack->data[stack->top]; } // 判断是否为运算符 int isOperator(char op) { return op == '+' || op == '-' || op == '*' || op == '/'; } // 获取运算符优先级 int getPriority(char op) { if (op == '*' || op == '/') return 2; else if (op == '+' || op == '-') return 1; else return 0; } // 执行表达式运算 int evaluateExpression(char *expression) { Stack operatorStack; // 运算符堆 Stack operandStack; // 操作数堆 initStack(&operatorStack, 100); initStack(&operandStack, 100); int i = 0; while (expression[i] != '\0') { if (expression[i] == ' ') { i++; continue; } if (isdigit(expression[i])) { int operand = 0; while (isdigit(expression[i])) { operand = operand * 10 + (expression[i] - '0'); i++; } push(&operandStack, operand); } else if (isOperator(expression[i])) { while (!isEmpty(&operatorStack) && getPriority(top(&operatorStack)) >= getPriority(expression[i])) { int op2 = pop(&operandStack); int op1 = pop(&operandStack); char op = pop(&operatorStack); switch (op) { case '+': push(&operandStack, op1 + op2); break; case '-': push(&operandStack, op1 - op2); break; case '*': push(&operandStack, op1 * op2); break; case '/': push(&operandStack, op1 / op2); break; } } push(&operatorStack, expression[i]); i++; } else if (expression[i] == '(') { push(&operatorStack, expression[i]); i++; } else if (expression[i] == ')') { while (!isEmpty(&operatorStack) && top(&operatorStack) != '(') { int op2 = pop(&operandStack); int op1 = pop(&operandStack); char op = pop(&operatorStack); switch (op) { case '+': push(&operandStack, op1 + op2); break; case '-': push(&operandStack, op1 - op2); break; case '*': push(&operandStack, op1 * op2); break; case '/': push(&operandStack, op1 / op2); break; } } pop(&operatorStack); // 弹出左括号 i++; } } while (!isEmpty(&operatorStack)) { int op2 = pop(&operandStack); int op1 = pop(&operandStack); char op = pop(&operatorStack); switch (op) { case '+': push(&operandStack, op1 + op2); break; case '-': push(&operandStack, op1 - op2); break; case '*': push(&operandStack, op1 * op2); break; case '/': push(&operandStack, op1 / op2); break; } } int result = pop(&operandStack); free(operatorStack.data); free(operandStack.data); return result; } int main() { char expression[100]; printf("请输入表达式:"); gets(expression); int result = evaluateExpression(expression); printf("计算结果:%d\n", result); return 0; } ``` 以上代码实现了对输入的表达式进行运算,其中使用两个堆分别存储运算符和操作数。通过比较运算符的优先级来决定是否进行运算,并将结果压入操作数堆中。最终得到的操作数堆中的唯一元素即为表达式计算结果。请注意,在输入表达式时需要注意空格的处理,以方便程序的解析。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值