数据结构 实验2:基于栈的中缀算术表达式求值

实验目的

掌握栈的基本操作算法的实现,包括栈初始化、进栈、出栈、取栈顶元素等
掌握利用栈实现中缀表达式求值的算法

实验内容

输入一个中缀算术表达式,求解表达式的值。运算包括“+”,“-”,“*”,“/”,”(”,”)”,“=”参加运算的数为double类型且为正数。(要求:直接使用中缀算术表达式进行计算,不能转换为后缀或前缀表达式再进行计算,只考虑二元运算即可)

输入要求:
多组数据,每组数据一行,对应一个算术表达式,每个表达式均以“=”结尾,当表达式只要一个“=”时,输入结束。参加运算的数为“double”类型。

输出要求:
对每组数据输出1行,为表达式的运算结果。保留2位小数

输入样例:
2+2=
20*(4.5-3)=
=

输出样例:
4.00
30.00

设计思路

文字可能表达的不够直观,大家可以去看看这个博客,有图会比较好理解一点:
https://blog.youkuaiyun.com/sinat_42483341/article/details/108901012?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522162322705516780255267988%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=162322705516780255267988&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allbaidu_landing_v2~default-6-108901012.first_rank_v2_pc_rank_v29&utm_term=%E5%9F%BA%E4%BA%8E%E6%A0%88%E7%9A%84%E4%B8%AD%E7%BC%80%E7%AE%97%E6%9C%AF%E8%A1%A8%E8%BE%BE%E5%BC%8F%E6%B1%82%E5%80%BC&spm=1018.2226.3001.4187

创建两个栈,一个放数字,一个放字符。从左到右读取中缀算术表达式,读到数字则将数字放入数字栈,读到字符则根据优先级判断计算顺序:遇到括号先算括号里面的;两个相邻的字符,先算优先级高的。当读到中缀算术表达式末尾时,输出表达式的计算结果,清空两个栈准备读取下一个中缀算术表达式,并进行计算。当中缀算术表达式为‘=’时,退出程序。

代码及注释

主要参考了这个代码:https://blog.youkuaiyun.com/weixin_44652407/article/details/103963877

#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <stack>
using namespace std;
int pre (char c)//返回优先级次序 
{
	if (c=='+'||c=='-' ) return 1;  // + - 返回1 
	else if (c=='*'||c=='/' ) return 2;  // * / 返回2 
	else return 0;  // = ( 返回0 
} 
void calculate (stack<double> &num,stack<char> &cha)//四则运算 
{
	double a=num.top();//读数字栈头 
	num.pop(); //出栈
	double b=num.top();//读数字栈头 
	num.pop();//出栈
	char c=cha.top();//读字符栈头
	cha.pop();//出栈
	switch (c)//加减乘除运算
	{
		case '+' : num.push(b+a); break;//加 
		case '-' : num.push(b-a); break;//减 
		case '*' : num.push(b*a); break;//乘 
		case '/' : num.push(b/a); break;//除 
	}
}
int main()
{
	stack<double> num;//存数字的栈 
	stack<char> cha;//存字符的栈 
	while (1)
	{
		char s[100];
		scanf ("%s",s);//读取中缀算术表达式 
		if (!strcmp(s,"=")) break;//只输入“=”则退出循环 
		for (int i=0;s[i]!='\0';i++)//遍历中缀算术表达式每一个字符 
		{
			if (isdigit(s[i]))//读取数字 
			{
				double temp=atof(&s[i]);//将字符串转为浮点型 
				num.push(temp);//将该数字入栈 
				while (isdigit(s[i])||s[i]=='.') i++;//已遍历完该数字,将i移到该数字最后一位  
				i--;
			}
			else //读取字符 
			{
				if (cha.empty()) cha.push(s[i]);//字符栈为空,入栈 
				else if (s[i]=='(')   cha.push(s[i]);//字符为左括号,入栈 
				else if (s[i]==')') //字符为右括号 
				{
					while (cha.top()!='(') calculate (num,cha);//计算括号内的表达式 
					cha.pop();//将左括号出栈 
				}
				else if (pre(s[i])>pre(cha.top())) cha.push(s[i]);//字符优先级大于字符栈头的优先级,入栈 
				else if (pre(s[i])<=pre(cha.top())) //字符优先级小于字符栈头的优先级
				{
					while (!cha.empty()&&pre(s[i])<=pre(cha.top()))  calculate (num,cha);//计算前面的表达式直到字符优先级大于字符栈头的优先级		
					cha.push(s[i]);//字符入栈 
				}
			}
		}
		printf ("%.2f\n",num.top());//输出中缀算术表达式的计算结果 
		num.pop();//清空数字栈 
		cha.pop();//清空字符栈 
	}
	return 0;
}

运行实例

在这里插入图片描述

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值