前面既然写了中缀转后缀的,那么现在说下中缀转前缀的,至于后缀(前缀)转中缀,可以根据相关的转换规则自行转换。

目的

将中缀表达式(即标准的表达式)转换为前缀表达式

例如:1+2*3+(4*5+6)7 转换成 ++1*23+*4567

转换原则:

与中缀转后缀不同,前者是顺序从左到右读取每一个字符,后者是从右到左顺序读取每一个字符,然后进行反转字符串。

  1. 如果遇到操作数,直接将操作数放入到prefix 中
  2. 如果遇到操作符,如果符号栈为空,直接放入符号栈中,如果符号栈不为空,则判断当前栈顶元素 
    • 如果当前栈顶元素为右括号‘)’,直接将操作符放入符号栈中
    • 如果当前栈顶元素的优先级大于操作数的优先级,则将栈顶元素移除,再次和判断移除后栈的栈顶元素比较优先级大小,直到当前栈顶元素小于或等于操作数优先级,将操作符放入符号栈中
  3. 如果遇到右括号,直接将右括号放入符号栈中
  4. 如果遇到左括号,将右括号到左括号之间的全部符号移出到prefix 中(记得左括号不要入栈,并且在最后将右括号从栈中删除)
  5. 重复1-4,直到最后一个字符被读入。
  6. 判断当前栈是否为空,如果不为空,将栈中的元素依次移出到prefix 中
  7. 翻转字符串

和中缀转后缀不同,进行优先级比较的时候,需要注意等号的问题

实例

首先,读入‘7’,并送到输出,然后‘*’被读入并压入栈中。接下来‘)’读入并送到栈中,此时状态如下: 
栈:*) 
输出:7

接下来读入‘6’,并送到输出,然后读入‘+’此时状态如下: 
栈:* ) + 
输出:7 6

然后读入‘5’,并送到输出,然后继续读入‘*’,由于‘*’的优先级比‘+’高,所以直接加入栈中,再将‘4’送到输出,因此状态如下: 
栈:* ) + * 
输出:7 6 5 4

下一个读入的符号‘(’,由于规则4,因此将符号栈中的操作符依次出栈,然后读入‘4’,并在最后将右括号弹出: 
栈:* 
输出: 7 6 5 4 * +

继续读入,此时读入‘+’,由优先级小于栈中‘*’的优先级,因此依照规则2,依次出栈,最后将‘+’入栈,接下来读入‘3’: 
栈:+ 
输出:7 6 5 4 * + * 3

往后读入的符号是‘*’,将‘*’入栈。然后将‘2’放入输出: 
栈:+ * 
输出:7 6 5 4 * + * 3 2

现在读入‘+’,由于符号栈中存在‘+’且它们的优先级相同,根据规则,除非,优先级大于栈顶元素,否则不出栈,依次栈中状态如下: 
栈:+ + 
输出:7 6 5 4 * + * 3 2 *

下一个读入‘1’: 
栈:+ + 
输出:7 6 5 4 * + * 3 2 * 1

现在输入为空,弹出所有栈中元素 
栈:空 
输出:7 6 5 4 * + * 3 2 * 1 + +

最后翻转 
输出:+ + 1 * 2 3 * + * 4 5 6 7

实现代码

/*利用栈将(中缀表达式)转换成(前缀表达式)e.g.1+2*3+(4*5+6)*7 转换成 ++1*23*+*4567infix(中缀表达式) : 1+2*3+(4*5+6)*7prefix(前缀表达式) : ++1*23*+*4567
*/
#include <algorithm>
#include <iostream>
#include <stack>
#include <string>
#include <map>
using namespace std;void InfixToPrefix(const string infix, string& prefix)
{stack<char> mark;                           // 符号栈map<char, int> priority;                    // 符号优先级priority['+'] = 0;priority['-'] = 0;priority['*'] = 1;priority['/'] = 1;int infix_length = infix.size();            // 中缀表达式的字符长度prefix.reserve(infix_length);               // 提高效率for(int i = infix_length - 1; i >= 0; --i) {switch(infix[i]) {case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9':prefix.push_back(infix[i]);break;case '+':case '-':case '*':case '/':if(!mark.empty()) {char markTop = mark.top();// 注意此处,与中缀转后缀有所不同while(markTop != ')' && priority[infix[i]] < priority[markTop]) {prefix.push_back(markTop);mark.pop();if(mark.empty()) {break;}markTop = mark.top();}}mark.push(infix[i]);break;case ')':mark.push(infix[i]);break;case '(':{char markTop = mark.top();while(markTop != ')') {prefix.push_back(markTop);mark.pop();markTop = mark.top();}mark.pop();}break;}}// 剩余的全部出栈while(!mark.empty()) {prefix.push_back(mark.top());mark.pop();}reverse(prefix.begin(), prefix.end());
}int main(int argc, char const *argv[])
{std::string infix = "1+2*3+(4*5+6)*7";std::string prefix;cout << "infix : " << infix << endl;InfixToPrefix(infix, prefix);cout << "prefix : " << prefix << endl; return 0;
}

利用栈实现中缀表达式转前缀表达式相关推荐

  1. 使用栈解决的一类经典问题:表达式转换及求值;中缀表达式;前缀表达式,后缀表达式,中缀转前缀;中缀转后缀;后缀表达式求值;波兰式,逆波兰式

    文章目录 背景知识 表达式转换问题(考研经典) 一:手工转换 (1)中缀转前缀和中缀转后缀 (2)前缀转中缀和后缀转中缀 二:用栈实现表达式转换 (1)中缀转后缀 (2)中缀转前缀 表达式计算问题(使 ...

  2. 中缀表达式到前缀表达式和后缀表达式

    1.算法思路 转化为后缀:从左到右遍历中缀表达式,遇到操作数,输出,遇到操作符,当前操作符的优先级大于栈顶操作符优先级,进栈,否则,弹出栈顶优先级大于等于当前操作符的操作符,当前操作符进栈.     ...

  3. 中缀表达式转为前缀表达式,然后根据前缀表达式计算结果

    相关原理 理论部分请参照上面的博客,写的很清楚. 好的我们来看代码 举个栗子 (9-((1+3)*2))/2 结果是0.5 def infix_to_prefix(expression):assert ...

  4. 数据结构 - 拓展突破(C++实现中缀表达式转前缀表达式,中缀表达式转后缀表达式,前缀表达式求值,中缀表达式求值)

    文章目录 1. C++中缀表达式转后缀表达式 2. C++中缀表达式转前缀表达式 3. C++后缀表达式求值 4. C++前缀表达式求值 1. C++中缀表达式转后缀表达式 输入中缀表达式样例: 2+ ...

  5. 中缀表达式转换为前缀表达式(lisp实现)

    使用weight.opcode和infix_to_prefix三个函数实现中缀表达式到前缀表达式的转换. 算符优先级函数weight 首先定义函数weight,它返回一个算术运算符(可简称为算符)的优 ...

  6. 【数据结构】中缀表达式转前缀表达式求值

    中缀表达式转前缀表达式求值 首先将中缀表达式转换成前缀表达式 前缀表达式中,操作符在前 例如:1+2*(5-3)+4 后缀表达式:++1*2-534 一.转换思路 转换思路为将输入的中缀表达式字符串从 ...

  7. 后缀表达式、前缀表达式

    后缀表达式和前缀表达式是什么呢? 前缀表达式:不包括括号的算术表达式,将运算符写在前面,操作数写在后面的表达式.为纪念其发明者波兰数学家Jan Lukasiewcz,也称"波兰式" ...

  8. 中缀表达式To前缀表达式 (python实现)

    1.名词解释 1.1 中缀表达式 普通表达式,即操作符位于操作数的中间.如''2+3*5'',''(2+3)*5''.这种表达式的特点是根据运算符的优先级不同,计算顺序不同.可以通过添加括号来改变计算 ...

  9. C语言中缀表达式转为前缀表达式

    思想: (1) 初始化两个栈:运算符栈S1和储存中间结果的栈S2: (2) 从右至左扫描中缀表达式: (3) 遇到操作数时,将其压入S2: (4) 遇到运算符时,比较其与S1栈顶运算符的优先级: (4 ...

  10. c语言前缀编码,C语言实现中缀表达式转前缀表达式

    1.实现的基本思想 (1) 初始化两个栈:运算符栈S1和储存中间结果的栈S2: (2) 从右至左扫描中缀表达式: (3) 遇到操作数时,将其压入S2: (4) 遇到运算符时,比较其与S1栈顶运算符的优 ...

最新文章

  1. C#设计技巧总结 网上转贴
  2. 分布式架构知识体系必读
  3. java招投标网站源码_基于jsp的招标系统-JavaEE实现招标系统 - java项目源码
  4. MySQL主主复制 外键_MySQL 组复制介绍
  5. 频繁项目集java实现_关联分析(2):Apriori产生频繁项集
  6. redis简单使用1
  7. centos nginx和tomcat集群
  8. UFO报表转换不成功!请检查文件版本或使用DOS文件转换工具
  9. mysql 分隔字符串的函数_Mysql 字符串分隔函数
  10. 在 MQL5 中使用 WININET。第二部分:POST 请求和文件
  11. itextpdf字体编码研究
  12. 基于python爬虫下载网站在线视频
  13. 笔耕不辍 | Redis入门
  14. 探究CSS3中的transition和transform属性方法使用
  15. 苹果软件测试的电池损耗准确,电池不耐用?教你如何检测iPhone电池损耗!
  16. matlab求二阶电路图,MATLAB实验MATLAB数值计算:二阶电路时域研究
  17. 2021年全球及中国天然橡胶产量、消费量及价格走势分析:中国市场需求量急速增涨[图]
  18. S3C2440-GPIO和jlink配置
  19. RT-thread-2022夏令营-学习总结-第二天
  20. bim要求计算机什么配置,BIM对电脑配置的要求

热门文章

  1. HTML+CSS大作业:旅游网页设计与实现——旅游风景网站6页HTML+CSS+JavaScript实训大作业 HTML+CSS大作业 HTML期末大作业
  2. AM335x片上ecap驱动移植
  3. 蓝牙无线自制串口模块连接穿越机配置工具
  4. Java项目:JSP会议-会议室管理系统
  5. 浅谈MMORPG服务器架构
  6. srand rand c语言,C语言srand和rand函数
  7. php网站403 forbidden,403 forbidden怎么解决
  8. Xbrowser远程连接显示灰屏
  9. vim 快速删除一个英文单词
  10. 浅谈Go语言中的面向对象