用stack处理中缀表达式【+、-、*、/、()】

文章目录

  • 题目描述
  • 思路
    • 使用getline()存储输入的字符串
    • 边读取边压栈
  • 完整代码


题目描述

使用stack处理括号化的表达式。当你看到一个左括号,将其记录下来。当你在一个左括号之后看到一个右括号,从stack中pop对象,直至遇到左括号,将左括号也一起弹出栈。然后将一个值(括号内的运算结果)push到栈中,表示一个括号化的(子)表达式已经处理完毕,被其运算结果所替代。


思路

使用getline()存储输入的字符串

是为了避免cin在提取字符串时遇到空格会终止读取的问题。例如:

// 当输入1 *2时
cin >> s; // s为1
getline(cin, s); // s为1 *2

边读取边压栈

创建两个栈:

  • 一个用来存运算符
  • 一个用来存操作数
    当遇到 “)” 时,弹出运算符栈中的运算符、和对应的操作数栈中的操作数并进行计算直到遇到 “(” ,完成后将这期间的运算结果压入操作数栈。例如:
    在这里插入图片描述
    处理 “ (,+,) ” 时,将1,2作为操作数从nums栈中弹出,将处理结果3压入nums栈中,当然, “ (,+,) ” 三个运算符全部弹出symbol栈。之后:
    在这里插入图片描述
    遇到右括号时,将乘号、左括号弹出栈,在这过程中将3、4作为操作数弹出nums栈进行运算,之后,将运算结果压入nums栈。

当处理完全部括号后,将symbol栈中的运算符清空——也就是将对应的运算都进行计算,(在此过程中,减法和除法要注意操作数的先后问题):
在这里插入图片描述
当symbol栈中为空时,nums栈中仅有一个元素,也就是最终的计算结果。


完整代码

#include <iostream>
#include <stack>
#include <string>using namespace std;void resolve(stack<double>& s1, stack<char>& s2){while((!s2.empty()) && (s2.top() != '(')){char temp = s2.top();s2.pop();double num1 = s1.top(); //second//cout << "num1: " << num1 << endl;s1.pop();double num2 = s1.top(); //first//cout << "num2: " << num2 << endl;s1.pop();if(temp == '*'){s1.push(num1*num2);//cout << "*" << endl;}if(temp == '/'){s1.push(num2/num1); // 注意操作数的顺序//cout << "/" << endl;}if(temp == '+'){s1.push(num1+num2);//cout << "+" << endl;}if(temp == '-'){ // 注意操作数的顺序s1.push(num2-num1);//cout << "-" << endl;}}if(!s2.empty()){ // 当symbol栈不为空的时候if(s2.top() == '('){ // 遇见左括号也会跳出上述循环    s2.pop();          // 因此无法执行while中的pop}                    // 程序会一直卡在左括号的位置}                      // 所以在这里补上pop避免上述问题}double calculate(string& s) {if(s.empty()){return 0;}stack<double> nums;stack<char> symbol;double num = 0;string temp = ""; // 存储连续数值字符for(size_t i = 0; i < s.size(); i++){if((s[i] >= '0' && s[i] <= '9') || s[i] == '.'){ // 数字temp += s[i]; // 连续数值字符}if(((s[i]<'0'||s[i]>'9')&&s[i]!=' ') || i==s.size()-1){ // 运算符if(!temp.empty()){num = stod(temp); // num存储连续数值字符的终值nums.push(num);}if(s[i] == ')'){resolve(nums, symbol);}else{switch (s[i]) {case '(':case '+':case '-':case '*':case '/':symbol.push(s[i]); // 上述五种运算符直接压栈}}num = 0;temp.clear(); // 清空temp以便存储下一个连续数值字符}}resolve(nums, symbol);return nums.top();
}bool pankong(string& str){ // 判断左右括号是否数量一致int left = 0;int right = 0;for(auto beg = str.begin(); beg != str.end(); beg++){switch (*beg) {case ')': right++; break;case '(': left++; break;}}if(left != right){cout << "左右括号数量不对等" << endl;return false;}else{return true;}
}int main()
{string str; // 表达式double over; // 最终值//cin >> str;getline(cin,str);if(!pankong(str)){ // 判断左右括号数量是否一致return -1;}over = calculate(str);cout << "over: " << over << endl;return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/443817.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

二维数组的查找

文章目录题目描述思路注意代码题目描述 在一个 n * m 的二维数组中&#xff0c;每一行都按照从左到右递增的顺序排序&#xff0c;每一列都按照从上到下递增的顺序排序。请完成一个高效的函数&#xff0c;输入这样的一个二维数组和一个整数&#xff0c;判断数组中是否含有该整数…

Springmvc,Spring MVC文件上传

Springmvc文件上传&#xff1a; 1.代码截图如下&#xff1a; 2.UploadController.java: package cn.csdn.controller;import java.io.File;import javax.servlet.http.HttpServletRequest;import org.springframework.stereotype.Controller; import org.springframework.ui.…

插入迭代器、流迭代器、反向迭代器、移动迭代器

文章目录前言插入迭代器inserterfront_inserterback_inserteriostream迭代器istream_iterator 读取输入流istream_iterator允许使用懒惰求值ostream_iterator操作反向迭代器reverse_iterator的base成员函数前言 除了为每个容器定义的迭代器之外&#xff0c;标准库在头文件iter…

泛型算法(lambda表达式、function类模板、bind函数适配器、迭代器类别、链表数据结构独有的算法)

文章目录概念find()函数迭代器令算法不依赖于容器但算法依赖于元素类型的操作算法永远不会执行容器的操作只读算法accumulate()函数从两个序列中读取元素&#xff08;equal函数为例&#xff09;迭代器作为参数形成两个序列equal()写容器元素的算法概念fill()fill_n()插入迭代器…

jsp,div 限制字数,超出部分用省略号代替

1.我是用struts2标签做的&#xff1a;如下&#xff1a; <% page language"java" import"java.util.*" pageEncoding"UTF-8"%> <% taglib prefix"s" uri"/struts-tags"%> <%String path request.getContext…

C++之关联容器

文章目录概述及类型mapsetpair类型概念初始化默认初始化提供初始化器允许的操作可以创建一个pair类的函数可以作为容器的类型关联容器迭代器概念map的迭代器set的迭代器是const的初始化map and setmultimap and multiset关联容器的操作额外的类型别名关联容器和算法删除元素添加…

动态内存、智能指针(shared_ptr、unique_ptr、weak_ptr)、动态数组

文章目录三种对象的分类三种内存的区别动态内存概念智能指针允许的操作智能指针的使用规范new概念内存耗尽/定位new初始化默认初始化直接初始化值初始化delete概念手动释放动态对象空悬指针shared_ptr类格式独有的操作make_shared函数shared_ptr的计数器通过new用普通指针初始化…

动态数组的简单应用

文章目录连接两个字符串字面常量题目注意代码输出结果处理输入的变长字符串题目注意代码连接两个字符串字面常量 题目 连接两个字符串字面常量&#xff0c;将结果保存在一个动态分配的char数组中。重写&#xff0c;连接两个标准库string对象。 注意 使用头文件cstring的str…

二分查找算法实现

文章目录思路代码以二分区间作为while判定条件以给定值作为while判定条件主函数思路 while判定条件的选择&#xff0c;注意最外层的return的内容就好。下面提供了两个代码版本。计算 mid 时需要防止溢出&#xff08;对应类型【如本例中的int】可能存不下&#xff09;&#xff…

根据中序、前序遍历重建二叉树

文章目录题目递归思路细节易错代码复杂度分析迭代思路细节易错代码复杂度分析题目 输入某二叉树的前序遍历和中序遍历的结果&#xff0c;请重建该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。 例如&#xff0c;给出 前序遍历 preorder [3,9,20,15,7] 中…

深搜+剪枝

文章目录题目思路注意代码复杂度分析题目 给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 单词必须按照字母顺序&#xff0c;通过相邻的单元格内的字母构成&#xff0c…

搜索+回溯问题(DFS\BFS详解)

文章目录题目思路DFS思路代码复杂度分析BFS思路代码复杂度分析题目 地上有一个m行n列的方格&#xff0c;从坐标 [0,0] 到坐标 [m-1,n-1] 。一个机器人从坐标 [0, 0] 的格子开始移动&#xff0c;它每次可以向左、右、上、下移动一格&#xff08;不能移动到方格外&#xff09;&am…

快速幂实现pow函数(从二分和二进制两种角度理解快速幂)

文章目录迭代实现快速幂思路int的取值范围快速幂从二进制的角度来理解从二分法的角度来理解代码复杂度分析进阶——超级次方思路倒序快速幂正序快速幂代码复杂度分析迭代实现快速幂 实现 pow(x, n) &#xff0c;即计算 x 的 n 次幂函数&#xff08;即&#xff0c;xn&#xff0…

n位数的全排列(需要考虑大数的情况)

文章目录题目思路代码题目 输入数字 n&#xff0c;按顺序打印出从 1 到最大的 n 位十进制数。比如输入 3&#xff0c;则打印出 1、2、3 一直到最大的 3 位数 999。 示例 1: 输入: n 1 输出: [1,2,3,4,5,6,7,8,9] 说明&#xff1a; 用返回一个整数列表来代替打印 n 为正整数 …

正则表达式匹配(动规)

文章目录题目思路转移方程特征再探 i 和 j代码题目 请实现一个函数用来匹配包含 . 和 * 的正则表达式。模式中的字符 . 表示任意一个字符&#xff0c;而 * 表示它前面的字符可以出现任意次&#xff08;含0次&#xff09;。在本题中&#xff0c;匹配是指字符串的所有字符匹配整…

在循环递增一次的数组中插入元素

文章目录题目思路如何建立左右区间&#xff1f;如何查找最高点&#xff1f;那我们怎么判断 num 到底处于什么样的位置呢&#xff1f;如何确定插入位置&#xff1f;插入元素代码题目 给一个只循环递增一次的数组 res&#xff0c;res 满足首元素大于等于尾元素&#xff0c;形如&…

表示数值的字符串(有限状态自动机与搜索)

文章目录题目思路一代码一思路二代码二题目 思路一 考察有限状态自动机&#xff08;参考jyd&#xff09;&#xff1a; 字符类型&#xff1a; 空格 「 」、数字「 0—9 」 、正负号 「 」 、小数点 「 . 」 、幂符号 「 eE 」 。 状态定义&#xff1a; 按照字符串从左到右的…

树的子结构

文章目录题目深搜深搜代码广搜广搜代码题目 输入两棵二叉树A和B&#xff0c;判断B是不是A的子结构。(约定空树不是任意一个树的子结构) B是A的子结构&#xff0c; 即 A中有出现和B相同的结构和节点值。 例如: 给定的树 A: 给定的树 B&#xff1a; 返回 true&#xff0c;因为…

写题过程中碰见的小问题

文章目录和--vector二维vector的初始化数组中最大的数max_element()数组所有元素之和accumulate()vector数组去重对pair类型的vector排序对元素都为正整数的vector利用sort默认的升序排列进行降序排列一维数组转二维数组size_t和int如何不用临时变量交换两个数?将类函数的形参…

LeetCode——二叉树序列化与反序列化

文章目录题目思路问题一问题二代码实现题目 请实现两个函数&#xff0c;分别用来序列化和反序列化二叉树。 设计一个算法来实现二叉树的序列化与反序列化。不限定序列 / 反序列化算法执行逻辑&#xff0c;你只需要保证一个二叉树可以被序列化为一个字符串并且将这个字符串反序…