本题考点:中缀表达式转后缀表达式。

难点:

  1. 带有小数的数字
  2. 数字可能带有正负号

题目描述:

算术表达式有前缀表示法、中缀表示法和后缀表示法等形式。日常使用的算术表达式是采用中缀表示法,即二元运算符位于两个运算数中间。请设计程序将中缀表达式转换为后缀表达式。

本题的测试点如下:

输入 输出 说明
2+3*(7-4)+8/4 2 3 7 4 - * + 8 4 / + 正常测试6种运算符
((2+3)*4-(8+2))/5 2 3 + 4 * 8 2 + - 5 / 嵌套括号
1314+25.5*12 1314 25.5 12 * + 运算数超过1位整数且有非整数出现
-2*(+3) -2 3 * 运算数前有正负号
123 123 只有一个数字

我们先来说明中缀转后缀的思路:

  1. 中缀转后缀
  • 建立一个操作符栈,用以临时存放操作符,建立一个数组或者队列,用以存放后缀表达式

    • 从左到右扫描中缀表达式,如果碰到操作数,就把操作数加入到后缀表达式中
    • 如果碰到操作符 op,就把其优先级和操作符栈顶操作符优先级比较
    • 如果 op 的优先级高于栈顶,就压入操作符栈(trick:初始化操作符栈时候增加一个 # 运算符为最低)
    • 如果低于或者等于栈顶,就将操作符栈的操作符不断弹出到后缀表达式中,直到 op 的优先级高于栈顶操作符
    • 重复直到中缀表达式扫描完毕,如果操作符栈中仍然有元素,则依次弹出放到后缀表达式中
  • 括号的处理方式

    • 将左括号的优先级设置为比 + - 更低,但是直接插入
    • 如果遇到右括号,那么直接从操作符栈中弹出到后缀表达式中,直到遇到左括号
  1. 后缀表达式的计算
  • 从左到右扫描后缀表达式,如果是操作数,就压入栈,如果是操作符,就连续弹出两个操作数,(后弹出的是第一操作数)
  • 然后进行操作符的操作,直到后缀表达式扫描完毕,这个时候结果栈中只剩一个元素,即为运算的结果

那么回归到本题,本题只要我们先把中缀转成后缀,所以我们可以先不计算出每个位置具体数值,而是用字符串保存下来即可。

完整代码和注释如下:

/*
Author: Veeupup
*/
#include <iostream>
#include <vector>
#include <string>
#include <stack>
#include <map>
using namespace std; vector<string> ans;
map<char, int> priority;
string operators = "+-*/()"; // 保存所有的计算符号 void trans(string str)
{
stack<char> ops;
ops.push('#');
string tempStr;
for (int i = 0; i < str.size(); i++)
{ // 检查是否是带符号的数字
// 1. 带正负号且前一个字符为运算符(i=0时直接带正负号的也是数字)
// 2. 当前字符为数字
if( ((str[i] == '-' || str[i] == '+') && (i == 0 || string("+-/*(").find(str[i-1])!=string::npos)) || isdigit(str[i]) )
{ // 把操作数加入到后缀式中
// 如果是正号就不用加入,负号或者数字本身都要加入
tempStr = str[i] != '+' ? str.substr(i, 1) : "";
while (i + 1 < str.size() && operators.find(str[i+1]) == string::npos)
{
tempStr += str[++i];
}
ans.push_back(tempStr);
}else { // 出现操作符
if(str[i] == '(')
ops.push(str[i]);
else if(str[i] == ')') {
while (ops.top() != '(')
{
ans.push_back(string(1, ops.top()));
ops.pop();
}
ops.pop();
}else {
while (priority[str[i]] <= priority[ops.top()])
{
ans.push_back(string(1, ops.top()));
ops.pop();
}
ops.push(str[i]);
}
}
}
while (ops.size() > 1)
{
ans.push_back(string(1, ops.top()));
ops.pop();
}
} int main()
{
priority['*'] = priority['/'] = 3;
priority['+'] = priority['-'] = 2;
priority['('] = 1;
priority['#'] = 0;
string str;
getline(cin, str);
trans(str);
for (int i = 0; i < ans.size(); i++)
cout << (i ? " " : "") << ans[i];
return 0;
}

路漫漫其修远兮,吾将上下而求索。

PTA-7-20 表达式转换(中缀转后缀,带括号,负数,小数转换)的更多相关文章

  1. C++做四则运算的MFC计算器(二)栈转换和计算后缀表达式

    上篇写了MFC界面搭建,这篇就写实现计算.涉及到数据结构,对新手很不友好. 虽然是MFC程序,但是能灵活地分离后台代码,自行构建控制台程序. 上篇文章链接:C++做四则运算的MFC计算器(一)MFC界 ...

  2. C++ 使用栈求解中缀、后缀表达式的值

    1. 前言 表达式求值对于有知识积累的你而言,可以通过认知,按运算符的优先级进行先后运算. 但对计算机而言,表达式仅是一串普通的信息而已,需要通过编码的方式告诉计算机运算法则,这个过程中栈起到了至关重 ...

  3. 栈的应用1——超级计算器(中缀与后缀表达式)C语言

    这里要学的程序主要用来实现一个功能——输入表达式输出结果,也就是一个计算器.效果如下: 这个程序主要有两个步骤:1.把中缀表达式转换为后缀表达式:2.计算后缀表达式的结果. 首先先明白几个问题: 1. ...

  4. Java数据结构和算法(六)——前缀、中缀、后缀表达式

    前面我们介绍了三种数据结构,第一种数组主要用作数据存储,但是后面的两种栈和队列我们说主要作为程序功能实现的辅助工具,其中在介绍栈时我们知道栈可以用来做单词逆序,匹配关键字符等等,那它还有别的什么功能吗 ...

  5. C++ 中缀转后缀表达式并求值

    //中缀转后缀 #include<iostream> #include<stack> using namespace std; int prio(char x){ ; ; ; ...

  6. Java数据结构和算法(六):前缀、中缀、后缀表达式

    前面我们介绍了三种数据结构,第一种数组主要用作数据存储,但是后面的两种栈和队列我们说主要作为程序功能实现的辅助工具,其中在介绍栈时我们知道栈可以用来做单词逆序,匹配关键字符等等,那它还有别的什么功能吗 ...

  7. 前缀、中缀、后缀表达式以及简单计算器的C++实现

    前缀表达式(波兰表达式).中缀表达式.后缀表达式(逆波兰表达式) 介绍 三种表达式都是四则运算的表达方式,用以四则运算表达式求值,即数学表达式的求解. 前缀表达式 前缀表达式是一种没有括号的算术表达式 ...

  8. 数据结构之栈—强大的四则复杂运算计算器(超过windows自带的科学计算器)【中缀转后缀表达式】

    比windows自带计算器还强的四则复杂运算计算器! 实测随机打出两组复杂算式:-7.5 * 6 / ( -2 + ( -6.5 -  -5.22 ) )与7.5+-3*8/(7+2) windows ...

  9. 前缀、中缀、后缀表达式及其相互转化的Java实现

    一.中缀表达式转换为前缀.后缀表达式 给个中缀表达式:a+b*c-(d+e)    首先根据运算符的优先级给所有运算单位加括号:((a+(b*c))-(d+e))    将运算符号移动到对应括号的前面 ...

随机推荐

  1. Windows Server 2012搭建SQL Server Always On踩坑全记录

    Windows Server 2012搭建SQL Server Always On踩坑全记录 环境信息: Windows Server 2012 R2 Sql Server 2012 整个搭建集群的过 ...

  2. 身为 Java 程序员必须掌握的 10 款开源工具!

    本文主要介绍Java程序员应该在Java学习过程中的一些基本和高级工具.如果你是一位经验丰富的Java开发人员,你可能对这些工具很熟悉,但如果不是,现在就是是开始学习这些工具的好时机.Java世界中存 ...

  3. 如何使用@import导入实现了ImportBeanDefinitionRegistrar接口的类?

    如何使用@import导入实现了ImportBeanDefinitionRegistrar接口的类?   在程序开发的时候,我们经常会遇见一个名词“接口”这也是我们做开发人员工作中必不可少的一个技术, ...

  4. Java设计模式之结构模式

    一.外观模式 分析:外观模式是为子系统的一组接口提供一个统一的界面,数据库JDBC连接应用就是外观模式的一个典型例子,特点:降低系统的复杂度,增加灵活性.结果:代码示例: public class D ...

  5. CollectionUtils工具类

    CollectionUtils工具类 这篇讲的CollectionUtils工具类是在apache下的,可以使代码更加简洁和安全. 使用前需导入依赖 <dependency> <gr ...

  6. 蚂蚁金服开源 | 可视化图形语法G2 3.3 琢磨

    G2 是蚂蚁金服数据可视化解决方案 AntV 的一个子产品,是一套数据驱动的.高交互的可视化图形语法. 经过两个多月密锣紧鼓的开发,400+次提交,G2 3.3版本今天终于和大家见面了.自上次3.2版 ...

  7. 前端每日实战:8# 视频演示如何用纯 CSS 创作一个充电 loader 特效

    效果预览 按下右侧的"点击预览"按钮在当前页面预览,点击链接全屏预览. https://codepen.io/zhang-ou/pen/deNqdV 可交互视频教程 此视频是可以交 ...

  8. 多道技术 进程 线程 协程 GIL锁 同步异步 高并发的解决方案 生产者消费者模型

    本文基本内容 多道技术 进程 线程 协程 并发 多线程 多进程 线程池 进程池 GIL锁 互斥锁 网络IO 同步 异步等 实现高并发的几种方式 协程:单线程实现并发 一 多道技术 产生背景 所有程序串 ...

  9. Matplotlib数据可视化(7):图片展示与保存

    In [1]: import os import matplotlib.image as mpimg from PIL import Image import matplotlib.pyplot as ...

  10. failed to open directory

    解决方法: 解决方案的路径不要包含中文!