给一个包含小数的中缀表达式 求出它的值

首先转换为后缀表达式然后利用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的更多相关文章

  1. c# 逆波兰式实现计算器

    语文不好,不太会组织语言,希望不要太在意. 如题,先简要介绍一下什么是逆波兰式  通常我们在写数学公式的时候  就是a+b+c这样,这种表达式称为中缀表达式,逆波兰式又称为后缀表达式,例如a+b 后缀 ...

  2. Java 实现《编译原理》中间代码生成 -逆波兰式生成与计算 - 程序解析

    Java 实现<编译原理>中间代码生成 -逆波兰式生成与计算 - 程序解析 编译原理学习笔记 (一)逆波兰式是什么? 逆波兰式(Reverse Polish notation,RPN,或逆 ...

  3. NYOJ 35 表达式求值(逆波兰式求值)

    http://acm.nyist.net/JudgeOnline/problemset.php?typeid=4 NYOJ 35 表达式求值(逆波兰式求值) 逆波兰式式也称后缀表达式. 一般的表达式求 ...

  4. shunting-yard 调度场算法、中缀表达式转逆波兰表达式

    中缀表达式 1*(2+3) 这就是一个中缀表达式,运算符在数字之间,计算机处理前缀表达式和后缀表达式比较容易,但处理中缀表达式却不太容易,因此,我们需要使用shunting-yard Algorith ...

  5. javascript:逆波兰式表示法计算表达式结果

    逆波兰式表示法,是由栈做基础的表达式,举个例子: 5 1 2 + 4 * + 3 -  等价于   5 + ((1 + 2) * 4) - 3 原理:依次将5 1 2 压入栈中, 这时遇到了运算符 + ...

  6. c++实现将表达式转换为逆波兰表达式

    https://github.com/Lanying0/lintcode 所属: 数据结构->线性结构->栈 问题: 给定一个表达式字符串数组,返回该表达式的逆波兰表达式(即去掉括号). ...

  7. [LeetCode]Evaluate Reverse Polish Notation(逆波兰式的计算)

    原题链接:http://oj.leetcode.com/problems/evaluate-reverse-polish-notation/ 题目描述: Evaluate the value of a ...

  8. HDU1237 简单的计算器 【堆】+【逆波兰式】

    简单的计算器 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Sub ...

  9. HDU1237 简单计算器 【栈】+【逆波兰式】

    简单计算器 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Subm ...

随机推荐

  1. E20170804-mk

    epic n. 史诗; 叙事诗; 史诗般的作品; estimate vt. 估计,估算; 评价,评论; 估量,估价; Sprint  vi. 冲刺,全速短跑; n. 全速短跑; 速度或活动的突然爆发; ...

  2. PropertyInfo 类

    [AttributeUsage(AttributeTargets.Property)] //Models 特性        public class CanWriteAttribute : Attr ...

  3. Android开发之Intent.Action Android中Intent的各种常见作用

    1 Intent.ACTION_MAIN String: android.intent.action.MAIN 标识Activity为一个程序的开始.比较常用. Input:nothing Outpu ...

  4. C#模拟百度登录并到指定网站评论回帖(二)

    序言: 回归正题:前面讲到的抓包分析的数据,是模拟登录要获得得必要信息(当然有些也不是必要的...我只是都列举出来这样有个对比)如果说,有哪个英文字母不知道什么意思的,可以问一下度娘,有不少前辈都发过 ...

  5. conda python虚拟环境

    #查看已安装的python包 conda list #查看当前有哪些虚拟环境 conda env list 或者 conda info -e #更新conda conda update conda # ...

  6. Jquery 可拖拽的Ztree

    比较懒,就只贴关键代码吧,自己把有用的属性全部打印出来了,也加了不少注释. 保存后涉及到的排序问题,刷新问题还未考虑到,后面有的话再加. $.fn.zTree.init($("#ztree& ...

  7. OpenAMP简介

    通常在AMP(非对称多处理)配置中,会采用在不同的处理核上运行不同的软件环境并执行各自的代码程序,各核心之间通力合作实现处理器性能的提升.在AMP系统中,所谓的主处理器通常是指最先启动且主要负责管理其 ...

  8. Android ScrollView里嵌套RecyclerView时,在RecyclerView上滑动时出现卡顿(冲突)的现象

    最近在项目中遇到一个现象,一个界面有一个RecyclerView(GridView型的),外面套了一层ScrollView,通过ScrollView上下滚动,但是在滑动的时候如果是在RecyclerV ...

  9. Angular——流程控制指令

    基本介绍 (1)ng-repeat,类似于for循环,对数组进行遍历 (2)ng-switch on,ng-switch-when,类似于switch,case 基本使用 ng-repeat < ...

  10. C#调用Win32 api时的内存操作

    一般情况下,C#与Win 32 Api的互操作都表现的很一致:值类型传递结构体,一维.二维指针传递IntPtr.在Win32 分配内存时,可以通过IntPtr以类似移动指针的方式读取内存.通过IntP ...