表达式求值问题-双栈模板化实现

这篇具有很好参考价值的文章主要介绍了表达式求值问题-双栈模板化实现。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

        好久不见,真的很久都没有更新博客了,最近很多事情,所以比较忙碌,没有时间每天都学算法,但是我会挤时间尽量做到,每两三天就更新博客,我会努力的,加油~

表达式求值问题-双栈模板化实现

    前言:计算器都见过吧,我们今天要讲的就是类似于计算器计算数据的简单实现,我们需要注意一些问题,比如运算符优先级,运算顺序等等问题,话不多说,冲冲冲!!!

目录

1.问题引入

2.问题分析及解决方法

如何设计优先级问题?

设计计算函数和启动计算条件

完整代码(可做为表达式计算模板使用)

3.金句频道


1.问题引入

表达式求值问题-双栈模板化实现

2.问题分析及解决方法

       首先,我们先来看一下整体思路:对于一个表达式,我们会读入括号,运算符和数字三种字符,我们需要将这些字符区分开再进行计算,为了保证运算的正确性,由运算符带来的优先级问题是我们解决这个问题的关键,解决了运算符优先级问题,我们就可以将运算符和数字分别存入一个栈中,用读取到' ) '和读取到优先级比已经保存在栈内的运算符来作为启动计算的条件(读到右括号,我们就可以将整个括号内部的部分算出来,再将算得结果压入保存数字的栈中用于后续的计算,而对于读取到优先级低的运算符,因为我们以栈存储数据,导致我们在计算的时候就会按逆序进行计算,所以,我们每次读取到一个运算符优先级低于栈顶的字符,都要先将栈内的运算符优先级高的运算符的结果算出,从而不影响运算顺序),最后,我们的运算符栈内如果还剩下元素,直接计算即可。

如何设计优先级问题?

       这里方法就有很多了,既可以用一个专门的函数来实现,也可以用STL的map键值来实现等等,这里我们采用第二种方法,该方法比较简单且代码易扩展,方便后序添加运算符。

unordered_map<char, int> p{ {'+',1},{'-',1},{'*',2},{'/',2} };//用来表示运算符的优先级,数字越大表示运算优先级越高

设计计算函数和启动计算条件

//计算函数
void f()
{
	//这里需要注意,我们的栈内保存的待运算数字和运算顺序是反着的,会影响减法和除法的计算
	auto b = num.top(); num.pop();
	auto a = num.top(); num.pop();
	auto c = op.top(); op.pop();
	if (c == '+')
		num.push(a + b);
	else if (c == '-')
		num.push(a - b);
	else if (c == '*')
		num.push(a * b);
	else if (c == '/')
		num.push(a / b);
	//如果想要再拓展其他运算,可在此处继续写下去

}

//计算启动条件
else if (s[i] == '(')//如果是左括号,直接入栈等待右括号到来再计算
			op.push(s[i]);
		else if (s[i] == ')')//右括号,准备开始计算结果
		{
			while (op.top() != '(') f();//做括号内的计算
			op.pop();//弹出左括号
		}
		else
		{
			while (!op.empty() && p[op.top()] >= p[s[i]]) f();//如果遇到优先级比前面已经入栈的运算符的优先极低的,则要先解决栈内的计算再将该优先级高的字符入栈
			op.push(s[i]);
		}

完整代码(可做为表达式计算模板使用)

#include<bits/stdc++.h>
#include <unordered_map>
using namespace std;
const int maxn = 1e5 + 10;

stack<int >num;
stack<char> op;//运算符

unordered_map<char, int> p{ {'+',1},{'-',1},{'*',2},{'/',2} };//用来表示运算符的优先级,数字越大表示运算优先级越高

void f()
{
	//这里需要注意,我们的栈内保存的待运算数字和运算顺序是反着的,会影响减法和除法的计算
	auto b = num.top(); num.pop();
	auto a = num.top(); num.pop();
	auto c = op.top(); op.pop();
	if (c == '+')
		num.push(a + b);
	else if (c == '-')
		num.push(a - b);
	else if (c == '*')
		num.push(a * b);
	else if (c == '/')
		num.push(a / b);
	//如果想要再拓展其他运算,可在此处继续写下去

}
int main()
{
	string s;
	cin >> s;
	for (int i = 0; i < s.size(); i++)
	{
		if (isdigit(s[i]))//注意,这里需要注意10以上的数,不能只看一个字符就完了
		{
			int j = i;
			int temp = 0;
			while (j < s.size() && isdigit(s[j]))
			{
				temp = temp * 10 + s[j++] - '0';
			}
			i = j-1;//j在退出循环之前已经自增了,所以要减去
			num.push(temp);
		}
		else if (s[i] == '(')//如果是左括号,直接入栈等待右括号到来再计算
			op.push(s[i]);
		else if (s[i] == ')')//右括号,准备开始计算结果
		{
			while (op.top() != '(') f();//做括号内的计算
			op.pop();//弹出左括号
		}
		else
		{
			while (!op.empty() && p[op.top()] >= p[s[i]]) f();//如果遇到优先级比前面已经入栈的运算符的优先极低的,则要先解决栈内的计算再将该优先级高的字符入栈
			op.push(s[i]);
		}
	}
	//如果最后栈内还剩下字符,直接计算即可
	while (op.size()) f();
	printf("%d\n", num.top());

	return 0;
}

     我们这里将计算函数和优先级单独设计,目的就是增加代码的可复用性,main函数内部没有涉及运算符的种类和其他的特殊处理,将特异性的功能封装成函数方便后序增添功能。

3.金句频道

       常常熬不住的时候也想找个靠山靠一下,可怎么找都会发现,有的山长满荆棘,有的山上全是野兽,所以你应该是自己的那座山。过度的依赖总会失掉自我,变得被动,不要总是整天“大佬带我飞”,让自己强起来才是一芳永逸的事。要相信每一次普通的改变,都可能改变原本的普通。

表达式求值问题-双栈模板化实现

 文章来源地址https://www.toymoban.com/news/detail-438154.html

到了这里,关于表达式求值问题-双栈模板化实现的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 文本单词查询复合表达式求值的实现案例分析

            本文讨论的“ 文本单词查询复合表达式求值的实现 ”案例,来自C++ primer第四版,该案例面向对象编程和泛型编程, 涉及类的继承、抽象、多态、句柄、标准IO库、容器、算法库 ,是综合性很强的程序         该程序实现文本中查找单个单词,“非”查询(使

    2024年01月23日
    浏览(26)
  • 简易计算器(详解用栈实现算术表达式求值)

    [问题描述] 一个算术表达式是由操作数(operand)、运算符(operator)和界限符(delimiter)组成的。假设操作数是 正实数 ,运算符只含 加减乘除 等四种运算符,界限符只含 左右括号 如:6+15*(21-8/4)。编程利用“ 运算符优先法 ”求算术表达式的值。 [基本要求] (1)读入一个合法的

    2024年02月08日
    浏览(38)
  • 【数据结构】利用顺序栈/链栈完成表达式求值(C语言实现)

    利用顺序栈完成表达式求值(将字符型转换为整型) 程序代码: #include stdio.h #include malloc.h #include stdlib.h #include math.h #define MAXSIZE 100 #define ElemType char #define LEN sizeof ( ElemType ) typedef struct {     ElemType * data;     int top; } SqStack ; void InitStack( SqStack * S ) {     S -data = ( ElemType *)

    2024年02月05日
    浏览(39)
  • 4.2 实现基于栈的表达式求值计算器(难度4/10)

    本作业主要考察:解释器模式的实现思想/栈结构在表达式求值方面的绝对优势 C++数据结构与算法夯实基础作业列表 通过栈的应用,理解特定领域设计的关键作用,给大家眼前一亮的感觉。深刻理解计算机语言和人类语言完美结合的杰作。是作业中的上等作品,是数据结构与

    2024年02月10日
    浏览(28)
  • c++表达式求值

    给定一个表达式,其中运算符仅包含 +,-, ,/(加 减 乘 整除),可能包含括号,请你求出表达式的最终值。 注意: 数据保证给定的表达式合法。题目保证符号 - 只作为减号出现,不会作为负号出现,例如,-1+2,(2+2) (-(1+1)+2) 之类表达式均不会出现。题目保表达式中所有数字均

    2024年01月21日
    浏览(27)
  • 栈|逆波兰表达式求值

    逆波兰表达式求值 逆波兰表达式就是后缀表达式,我们平时写的带括号的是中缀表达式。区分中缀表达式和后缀表达式 就是 操作数 和 操作符 的先后关系。 操作符在后 就是后缀表达式 后缀表达式 的用途就是 让计算机直到计算的先后顺序! 比如 我们中缀表达式 a * (b -

    2024年04月11日
    浏览(38)
  • 表达式求值和转换

    2024年02月06日
    浏览(27)
  • C++ 数据结构 栈 中缀表达式转后缀表达式并求值

    写在前面,这里用的是我自己写的Stack类,并非STL,实现方法为静态数组,但使用过程中的函数方法一样,无伤大雅。(完整code和Stack_static类赋在最后) 1.从左到右遍历 2.数,即参与运算数,直接放进后缀表达式之后 3.左括号 ,直接压入栈(因为括号的优先级最高,无需判断

    2024年02月03日
    浏览(37)
  • 数据结构之表达式求值

     前言 运用堆栈解决表达式的求值,代码思路为: 1.定义两个栈,一个char类型的栈用于存放运算符(ysf)一个int类型的栈用于存放操作数(czs) 如一个表达式3+6*9,将“+”,“*”入ysf栈,将“3”“6”“9”入czs栈 2.运用getchar进行数据的录入,如果接收的是运算符,将其插入到运

    2024年04月29日
    浏览(27)
  • 中缀表达式求值(栈的应用)

    AcWing算法基础课-3302.表达式求值 给定一个表达式,其中运算符仅包含 +,-,*,/ (加 减 乘 整除),可能包含括号,请你求出表达式的最终值。 注意: 数据保证给定的表达式合法。 题目保证符号 - 只作为减号出现,不会作为负号出现,例如, -1+2 , (2+2)*(-(1+1)+2) 之类表达式均不

    2024年02月05日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包