使用栈实现表达式求值

使用栈实现表达式求值任何一个表达式都是由操作数,运算符,界限符组成的。操作数即是参加运算的数值或者变量,运算符则是加减乘除等组成,为简单起见,这里只实现加减乘除的运算,而常见的界限符则是左右括号和终止符。在运算过程中,要判断两个先后出现的运算符之间的优先顺序。为了实现算法,设置两个工作栈:用于存储运算符的栈opter,以及用于存储操作数及中间结果的栈opval。算法基本思想如下:(1)首先将操作数栈opv

大家好,又见面了,我是你们的朋友全栈君。

为了实现用栈计算算数表达式的值,需设置两个工作栈:用于存储运算符的栈opter,以及用于存储操作数及中间结果的栈opval。

算法基本思想如下:

(1)首先将操作数栈opval设为空栈,而将’#’作为运算符栈opter的栈底元素,这样的目的是判断表达式是否求值完毕。

(2)依次读入表达式的每个字符,表达式须以’#’结尾,若是操作数则入栈opval,若是运算符,则将此运算符c与opter的栈顶元素top比较优先级后执行相应的操作,(具体操作如下:(i)若top的优先级小于c,即top<c,则将c直接入栈opter,并读入下一字符赋值给c;(ii)若top的优先级等于c,即top=c,则弹出opter的栈顶元素,并读入下一字符赋值给c,这一步目的是进行括号操作;(iii)若top优先级高于c,即top>c,则表明可以计算,此时弹出opval的栈顶两个元素,并且弹出opter栈顶的的运算符,计算后将结果放入占opval中。)直至opter的栈顶元素和当前读入的字符均为’#’,此时求值结束。

算符间的优先关系如下表所示:

使用栈实现表达式求值

表中需要注意的是θ1为opter的栈顶元素,θ2位从表达式中读取的操作符,此优先级表可以用二维数组实现,具体见代码(表来源:严蔚敏《数据结构》)。

具体代码如下:

#include<iostream>     //输入的表达式要以'#'结尾,如‘5+6*3/(3-1)#’
#include<cstring>
#include<cstdio>
#include<cctype>
#include<stack>
using namespace std;

stack<char> opter;    //运算符栈
stack<double> opval;  //操作数栈

int getIndex(char theta)   //获取theta所对应的索引
{
	int index = 0;
	switch (theta)
	{
	case '+':
		index = 0;
		break;
	case '-':
		index = 1;
		break;
	case '*':
		index = 2;
		break;
	case '/':
		index = 3;
		break;
	case '(':
		index = 4;
		break;
	case ')':
		index = 5;
		break;
	case '#':
		index = 6;
	default:break;
	}
	return index;
}

char getPriority(char theta1, char theta2)   //获取theta1与theta2之间的优先级
{
	const char priority[][7] =     //算符间的优先级关系
	{
		{ '>','>','<','<','<','>','>' },
		{ '>','>','<','<','<','>','>' },
		{ '>','>','>','>','<','>','>' },
		{ '>','>','>','>','<','>','>' },
		{ '<','<','<','<','<','=','0' },
		{ '>','>','>','>','0','>','>' },
		{ '<','<','<','<','<','0','=' },
	};

	int index1 = getIndex(theta1);
	int index2 = getIndex(theta2);
	return priority[index1][index2];
}

double calculate(double b, char theta, double a)   //计算b theta a
{
	switch (theta)
	{
	case '+':
		return b + a;
	case '-':
		return b - a;
	case '*':
		return b * a;
	case '/':
		return b / a;
	default:
		break;
	}
}

double getAnswer()   //表达式求值
{
	opter.push('#');      //首先将'#'入栈opter
	int counter = 0;      //添加变量counter表示有多少个数字相继入栈,实现多位数的四则运算
	char c = getchar();
	while (c != '#' || opter.top() != '#')   //终止条件
	{
		if (isdigit(c))   //如果c在'0'~'9'之间
		{
			if (counter == 1)   //counter==1表示上一字符也是数字,所以要合并,比如12*12,要算12,而不是单独的1和2
			{
				double t = opval.top();
				opval.pop();
				opval.push(t * 10 + (c - '0'));
				counter = 1;
			}
			else
			{
				opval.push(c - '0');     //将c对应的数值入栈opval
				counter++;
			}
			c = getchar();
		}
		else
		{
			counter = 0;   //counter置零
			switch (getPriority(opter.top(), c))   //获取运算符栈opter栈顶元素与c之间的优先级,用'>','<','='表示
			{
			case '<':               //<则将c入栈opter
				opter.push(c);
				c = getchar();
				break;
			case '=':               //=将opter栈顶元素弹出,用于括号的处理
				opter.pop();
				c = getchar();
				break;
			case '>':               //>则计算
				char theta = opter.top();
				opter.pop();
				double a = opval.top();
				opval.pop();
				double b = opval.top();
				opval.pop();
				opval.push(calculate(b, theta, a));
			}
		}
	}
	return opval.top();   //返回opval栈顶元素的值
}

int main()
{
	//freopen("test.txt", "r", stdin);
	int t;     // 需要计算的表达式的个数
	cin >> t;
	getchar();
	while (t--)
	{
		while (!opter.empty())opter.pop();
		while (!opval.empty())opval.pop();
		double ans = getAnswer();
		cout << ans << endl<< endl;
		getchar();
	}
	return 0;
}

结果:

使用栈实现表达式求值

使用栈实现表达式求值

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/148806.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • intelli idea2021激活码【在线注册码/序列号/破解码】

    intelli idea2021激活码【在线注册码/序列号/破解码】,https://javaforall.cn/100143.html。详细ieda激活码不妨到全栈程序员必看教程网一起来了解一下吧!

  • vue入门教程(一)「建议收藏」

    vue入门教程(一)「建议收藏」1.vue简介1.1vue是什么官网:https://cn.vuejs.org/Vue是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue被设计为可以自底向上逐层应用。Vue的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue也完全能够为复杂的单页应用提供驱动。1.2vue的特点1)遵循MVVM模式2)编码简洁,体积小,运行效率高,适合移动/PC端开发.

  • linux sort 命令详解[通俗易懂]

    linux sort 命令详解[通俗易懂]sort是在Linux里非常常用的一个命令,管排序的,集中精力,五分钟搞定sort,现在开始!1sort的工作原理sort将文件的每一行作为一个单位,相互比较,比较原则是从首字符向后,依次按ASCI

  • db4o数据库文件_繁忙的Java开发人员指南db4o,使用db4o进行数据库重构

    db4o数据库文件_繁忙的Java开发人员指南db4o,使用db4o进行数据库重构存档日期:2019年5月13日|首次发布:2007年5月22日重构Java™代码比重构关系数据库要简单得多,但是幸运的是,对象数据库的情况并非如此。在《繁忙的Java开发人员db4o指南》的这一期中,TedNeward向您介绍了他最喜欢的对象数据库的另一个优点:db4o将重构简化到几乎没有用处。此内容不再被更新或维护。全文以PDF格式“按原样”提供。随着技术的飞速发展,…

  • python安装dlib库_pycharm安装dlib失败

    python安装dlib库_pycharm安装dlib失败dlib库可以实现人脸的检测,所以有些小伙伴在学习人脸识别和检测的时候有可能会用到此库。本人python版本为3.7,在dlib的下载官网上只找到python3.6的版本,当然还有很多文章上写的是安装cmake进行编译再安装boost然后再使用pipinstalldlib安装即可,但是本人试了很多还是不行。3.7版本的dlib资源文件在csdn的其它文章中就有,淘宝0.5元即可下载,下载完成后将文件放置python文件下的Scripts文件夹中即可,结果如图。然后启动cmd,使用pipinstall

  • jsrender

    jsrender

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号