数据结构课程设计(选):算术表达式求值

1.任务:

[问题描述]

一个算术表达式是由操作数(operand)、运算符(operator)和界限符(delimiter)组成的。假设操作数是正实数,运算符只含加减乘除等四种运算符,界限符有左右括号和表达式起始、结束符“#”,如:#6+15*(21-8/4)#。引入表达式起始、结束符是为了方便。编程利用“运算符优先法”求算术表达式的值。

[基本要求]

(1)从键盘或文件读入一个合法的算术表达式,输出正确的结果。

(2)显示输入序列和栈的变化过程。

(3)考虑算法的健壮性,当表达式错误时,要给出错误原因的提示。

(4)实现非整数的处理(*)。

2.采用的数据结构

        采用栈的结构

3.算法设计思想

        依次读入表达式中的每一个字符,若为输入为数字,则加入数字栈;若读取为操作符,当其优先级高于栈顶操作符优先级,则将它加入符号栈,当其优先级低于栈顶操作符时,则符号栈弹出符号,数字栈弹出两个数字进行计算,将计算所得结果压入数字栈,操作符继续与栈顶操作符进行优先级比较,直至最后读入’#’。时间复杂度T(n)=O(n).

        同时,程序可以对于表达式出现的错误进行提示,例如输入表达式格式不正确,除数为零等,实现了算法的健壮性。

4.源程序:

#include <iostream>
#include <math.h>
using namespace std;

char input[128];
int position;

double Calculation(double a,double b,char op)          //定义运算 
{
	switch (op) 
	{
	    case '+':
	    	return a+b;
	    	break;
    	case '-':
	    	return a-b;
	    	break;
	    case '*':
	    	return a*b;
	    	break;
	    case '/':
	    	return a/b;
	    	break;
    	default:
	    	printf("表达式中含有错误运算符!");
	    	exit -1;
	}
}

int Provity(char op)
{
	if(op=='*' || op=='/')
	{
		return 2;
	}
	else if(op=='+' || op=='-') 
	{
		return 1;
	}
	else if(op=='(')
	{
		return 0;
	}
	else if(op=='#')
    {
    	return -1;
	}
	else
	{
		printf("表达式中含有错误运算符!");
		exit -1;
	}
}

double GetNum(int &position)                           //提取输入的表达式中的数字 
{
	int integer=0;
	double decimal=0;
	while (input[position]>= '0' && input[position]<= '9') 
	{
		integer=integer*10;
		int t;
		t=input[position]-'0';
		integer=integer+t;
		position++;
	}
	if (input[position]=='.') 
	{
		position++;
		int t;
		double w=0.1;
		while (input[position]>='0' && input[position]<= '9') 
		{
			t=input[position]-'0';
			decimal=decimal+t*w;
			w=w*0.1;
			position++;
		}
	}
	return integer+decimal;
}
 
double Compute()                                       //计算表达式 
{
	char opstack[64];                                  //符号栈 
	double numstack[128];                                //数字栈 
	opstack[0]='#';
    int optail=1; 
    int numtail=0;
	if (input[0] != '#') 
	{
		printf("输入公式有误!");
		exit -1;
	}
	int position=1; 
	while (input[position]!='#') 
	{           
		if(input[position]== '(')                    	          //当输入'('时
		{
			opstack[optail++]='(';
			printf("运算符'('入栈\n");
			position++;
		}
		else if (input[position] == ')') 	           	           //当输入')'时
		{
			position++;
			while (opstack[--optail]!='(') 
			{
				double a;
				a=numstack[--numtail];
				printf("数字%f出栈\n",a);
				double b;
				b=numstack[--numtail];
				printf("数字%f出栈\n",b);
				char op;
				op=opstack[optail];
				printf("运算符'%c'出栈\n", op);
				if (op=='/' && a==0) 
				{
					printf("ERROR: 0不能做除数!\n");
					exit -1;
				}
				double result;
				result=Calculation(b,a,op);
				numstack[numtail++]=result;
				printf("数字%f入栈\n", result);
			}
			printf("运算符'(''出栈\n");
		}
		else if (input[position]>='0'&&input[position]<='9') 		//如果是数字
		{
			double num;
			num=GetNum(position);
			numstack[numtail++]=num;
			printf("数字%f入栈\n", num);
		}
		else 		                                                //其它运算符
		{
			while (Provity(input[position]) <= Provity(opstack[--optail]) )
			{
				double a;
				a=numstack[--numtail];
				printf("数字%f出栈\n",a);
				double b;
				b=numstack[--numtail];
				printf("数字%f出栈\n",b);
				char op;
				op=opstack[optail];
				printf("运算符'%c'出栈\n", op);
				if (op == '/' && a==0) 
				{
					printf("ERROR: 0不能做除数!\n");
					exit -1;
				}
				double result;
				result=Calculation(b,a,op);
				numstack[numtail++]=result;
				printf("数字%f入栈\n", result);
			}
            optail++;
			opstack[optail++]=input[position];
			printf("运算符'%c''入栈\n", input[position]);
			position++;
		}
	}
	while (opstack[--optail]!= '#') 
	{
		double a;
		a=numstack[--numtail];
		printf("数字%f出栈\n",a);
		double b;
		b=numstack[--numtail];
		printf("数字%f出栈\n",b);
		char op;
		op=opstack[optail];
		printf("运算符'%c'出栈\n", op);
		if (op == '/' && a==0) 
		{
			printf("ERROR: 0不能做除数!\n");
			exit -1;
		}
		double result;
		result=Calculation(b,a,op);
		numstack[numtail++]=result;
		printf("数字%f入栈\n", result);
	}
	return numstack[--numtail];
} 

int main() 
{
	printf("请输入算术表达式,示例:#6+15*(21-8/4)#\n");
	cin>>input;
	printf("运算结果为:%f",Compute());
	return 0;
}

5.源程序测试数据及结果

算术表达式测试数据及测试结果

  • 7
    点赞
  • 50
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值