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

首先转换为后缀表达式然后利用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. jeesite ckfinder mac/linux 文件上传路径设置

    背景: 如果你使用的是Mac 或者 Ubuntu 这种 Unix系统的话,你一定知道Unix系统的文件路径分隔符是 / 而Windows系统文件分隔符是 \ 当你设置了jeesite.properti ...

  2. eclipse的快捷键---调试

    1:查看类或接口的方法 Ctrl+T 2:debug调试查看信息 Ctrl+Shift+i 3:debug调试快捷键 (1):F11好像是重新运行debug. (2):F8直接输出结果.(3):F5单 ...

  3. php自动加载的两个函数__autoload和__sql_autoload_register

    一.__autoload 这是一个自动加载函数,在PHP5中,当我们实例化一个未定义的类时,就会触发此函数.看下面例子: printit.class.php //文件 <?php class P ...

  4. python自动化测试学习笔记-4常用模块

    常用模块 1.os 2.sys 3.random 4.string 5.time 6.hashlib 一.os模块 os模块主要用来操作文件.目录,与操作系统无关.要使用os模块首先要导入OS模块,用 ...

  5. HTML--使用mailto在网页中链接Email地址

    <a>标签还有一个作用是可以链接Email地址,使用mailto能让访问者便捷向网站管理者发送电子邮件.我们还可以利用mailto做许多其它事情.下面一一进行讲解,请看详细图示: 注意:如 ...

  6. windows怎么进如debug调试

    主要说一下64位Win7使用debug程序的方法 首先你要下载一个DOSBOX程序 这个程序是一个dos模拟器 这个程序的制作目的是运行经典的DOS游戏 -.- 下载地址:http://www.dos ...

  7. python网络爬虫之图片链家在技术.seleninum和PhantonJS

    一.什么是图片懒加载? 案例分析:抓取站长素材http://sc.chinaz.com/中的图片数据 #!/usr/bin/env python # -*- coding:utf-8 -*- impo ...

  8. ACM_Jack拆炸弹(深搜)

    Jack拆炸弹 Time Limit: 2000/1000ms (Java/Others) Problem Description: 在一个由n*n个格子组成的监狱里被恐怖份子安置了一个定时炸弹.其中 ...

  9. hibernate.cfg.xml配置

    hibernate.hbm2ddl.auto 配置: create:每次加载hibernate时都会删除上一次的生成的表,然后根据你的model类再重新来生成新表,哪怕两次没有任何改变也要这样执行,这 ...

  10. tp5.0分页样式调控

    基础的分页调用 /** * 控制器部分代码 */ //实例化模型 $areasModel=new Areas(); //分页数据集 $listarea=$areasModel->paginate ...