中缀表达式转逆波兰式(后缀表达式)求值 C++ Stack
给一个包含小数的中缀表达式 求出它的值
首先转换为后缀表达式然后利用stack求出值
转换规则:
如果字符为'(' push
else if 字符为 ')'
出栈运算符直到遇到‘('
else if 字符为‘+’,’-‘,’*‘,’/‘
{
if 栈为空或者上一个运算符的优先级小于当前运算符
push
else
{
运算符优先级小于等于栈顶运算符的优先级,出栈
然后!将当前运算符入栈!
}
}
代码
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<sstream>
#include<algorithm>
#include<queue>
#include<deque>
#include<iomanip>
#include<vector>
#include<cmath>
#include<map>
#include<stack>
#include<set>
#include<fstream>
#include<memory>
#include<list>
#include<string>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
#define MAXN 1100
#define L 31
#define INF 1000000009
#define eps 0.00000001
/*
1.000+2/4=
((1+2)*5+1)/4=
首先把中缀表达式转换为后缀表达式!(注意点运算符求值)
转换后的结果用一个string vector来表示
然后从前到后求值,pop两个数字 计算结果然后插入到stack中
*/
string str;
vector<string> trans;
stack<char> S;
stack<float> cal;
map<char, int> pri;
void Read()
{
string tmp;
trans.clear();
while (!S.empty())
S.pop();
while (!cal.empty())
cal.pop();
for (int i = ; i < str.size() - ; i++)// 特殊考虑( ) .
{
if (str[i] == '(')
{
if (!tmp.empty())
{
trans.push_back(tmp);
tmp.clear();
}
S.push(str[i]);
}
else if (str[i] == ')')
{
if (!tmp.empty())
{
trans.push_back(tmp);
tmp.clear();
}
while (!S.empty() && S.top() != '(')
{
string ttt = "";
ttt.push_back(S.top());
trans.push_back(ttt);
S.pop();
}
if (!S.empty() && S.top() == '(')
S.pop();
}
else if (str[i] == '+' || str[i] == '-' || str[i] == '*' || str[i] == '/')
{
if (!tmp.empty())
{
trans.push_back(tmp);
tmp.clear();
}
if (S.empty() || pri[S.top()]<pri[str[i]])
{
S.push(str[i]);
continue;
}
else
{
while (!S.empty() && pri[S.top()] >= pri[str[i]])
{
string ttt = "";
ttt.push_back(S.top());
trans.push_back(ttt);
S.pop();
}
S.push(str[i]);
}
}
else
{
tmp.push_back(str[i]);
}
}
if (!tmp.empty())
{
trans.push_back(tmp);
tmp.clear();
}
while (!S.empty())
{
string ttt = "";
ttt.push_back(S.top());
trans.push_back(ttt);
S.pop();
}
}
float solve()//计算转化出的后缀表达式的值
{
while (!cal.empty())
cal.pop();
for (int i = ; i < trans.size(); i++)
{
if (trans[i] == "+" || trans[i] == "-" || trans[i] == "*" || trans[i] == "/")
{
float a, b;
a = cal.top();
cal.pop();
b = cal.top();
cal.pop();
if (trans[i] == "+")
cal.push(a + b);
else if (trans[i] == "-")
cal.push(b - a);
else if (trans[i] == "*")
cal.push(a * b);
else
cal.push(b / a);
}
else
{
cal.push(atof(trans[i].c_str()));
}
}
return cal.top();
}
int main()
{
int n;
cin >> n;
pri['+'] = pri['-'] = , pri['*'] = pri['/'] = , pri['('] = pri[')'] = -;
while (n--)
{
cin >> str;
Read();
printf("%.2f\n",solve());
}
return ;
}
中缀表达式转逆波兰式(后缀表达式)求值 C++ Stack的更多相关文章
- c# 逆波兰式实现计算器
语文不好,不太会组织语言,希望不要太在意. 如题,先简要介绍一下什么是逆波兰式 通常我们在写数学公式的时候 就是a+b+c这样,这种表达式称为中缀表达式,逆波兰式又称为后缀表达式,例如a+b 后缀 ...
- Java 实现《编译原理》中间代码生成 -逆波兰式生成与计算 - 程序解析
Java 实现<编译原理>中间代码生成 -逆波兰式生成与计算 - 程序解析 编译原理学习笔记 (一)逆波兰式是什么? 逆波兰式(Reverse Polish notation,RPN,或逆 ...
- NYOJ 35 表达式求值(逆波兰式求值)
http://acm.nyist.net/JudgeOnline/problemset.php?typeid=4 NYOJ 35 表达式求值(逆波兰式求值) 逆波兰式式也称后缀表达式. 一般的表达式求 ...
- shunting-yard 调度场算法、中缀表达式转逆波兰表达式
中缀表达式 1*(2+3) 这就是一个中缀表达式,运算符在数字之间,计算机处理前缀表达式和后缀表达式比较容易,但处理中缀表达式却不太容易,因此,我们需要使用shunting-yard Algorith ...
- javascript:逆波兰式表示法计算表达式结果
逆波兰式表示法,是由栈做基础的表达式,举个例子: 5 1 2 + 4 * + 3 - 等价于 5 + ((1 + 2) * 4) - 3 原理:依次将5 1 2 压入栈中, 这时遇到了运算符 + ...
- c++实现将表达式转换为逆波兰表达式
https://github.com/Lanying0/lintcode 所属: 数据结构->线性结构->栈 问题: 给定一个表达式字符串数组,返回该表达式的逆波兰表达式(即去掉括号). ...
- [LeetCode]Evaluate Reverse Polish Notation(逆波兰式的计算)
原题链接:http://oj.leetcode.com/problems/evaluate-reverse-polish-notation/ 题目描述: Evaluate the value of a ...
- HDU1237 简单的计算器 【堆】+【逆波兰式】
简单的计算器 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Sub ...
- HDU1237 简单计算器 【栈】+【逆波兰式】
简单计算器 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Subm ...
随机推荐
- canvas 文字转化为粒子
var canvas = document.createElement('canvas'); var cxt = canvas.getContext('2d'); var W = canvas.wid ...
- Hadoop Hive概念学习系列之hive里的扩展接口(CLI、Beeline、JDBC)(十六)
<Spark最佳实战 陈欢>写的这本书,关于此知识点,非常好,在94页. hive里的扩展接口,主要包括CLI(控制命令行接口).Beeline和JDBC等方式访问Hive. CLI和B ...
- AdminLTE介绍和zTree的简单使用
一.AdminLTE介绍 1.介绍 AdminLTE是一个开源的后台控制面板和仪表盘 WebApp 模板,是建立在Bootstrap3框架和JQuery之上的开源模板主题工具,它提供了一系列响应的 ...
- 关于编辑器对<input>标签报错提示“表单输入没有相关label”的问题
相信很多朋友在制作表单的时候,我们的编辑器会有下图的相关提示吧 我们发现虽然这样并不影响我们的正常使用,但是看着这样的报错提示总是很让人心烦,那么这到底是为什么呢? 其实,这是因为编辑器建议我们在使用 ...
- Hive扩展功能(四)--HiveServer2服务
软件环境: linux系统: CentOS6.7 Hadoop版本: 2.6.5 zookeeper版本: 3.4.8 主机配置: 一共m1, m2, m3这五部机, 每部主机的用户名都为centos ...
- WEB文件上传之apache common upload使用(一)
文件上传一个经常用到的功能,它有许多中实现的方案. 页面表单 + RFC1897规范 + http协议上传 页面控件(flash/html5/activeX/applet) + RFC1897规范 + ...
- JS——冒泡案例
模态框 1.因为a链接和和顶级document都注册了单击事件,所以要阻止a链接向父级盒子冒泡,不然又会从document的单击事件走一遍 2.在document的单击事件中,只需要判断触发事件的目标 ...
- java攻城狮之路--复习xml&dom_pull编程
xml&dom_pull编程: 1.去掉欢迎弹窗界面:在window项的preferences选项中输入“configuration center” 找到这一项然后 把复选框勾去即可. ...
- CSS3 background-origin 属性
CSS3 background-origin 属性 padding-box 背景图像相对于内边距框来定位. border-box 背景图像相对于边框盒来定位. content-box 背景图像相对于内 ...
- Gradle与Makefile构建工具的对比
随着Android Studio的普及,越来越多的Android开发者也要开始了解和学习Gradle这款强大的代码构建工具了.我们在学习和了解一项新事物的时候,最快速的方法往往是与已知的事物进行比较, ...