核心代码与思路:

int GetExprValue(vector<string> srcVec)   //根据后缀表达式求值
{stack<int> temp;char op = '\0';int a = 0;int b = 0;for (int i = 0; i < srcVec.size(); i++) {op = srcVec[i][srcVec[i].length() - 1];if (isdigit(op)) {temp.push(atoi(srcVec[i].c_str())); //如果是数字则直接入栈} else {a = temp.top();                     //否则从栈中取出两个操作数进行计算(注意操作数的左右顺序)temp.pop();                            //然后将计算的值入栈b = temp.top();temp.pop();temp.push(CalFunc(b, op, a));}}return temp.top();
}vector<string> GetSufix(string src)
{vector<string> dest;stack<char> opStack;int i = 0;string temp = "";while (i < src.length()) {if (isdigit(src[i])) {  //如果遇到数字就读取一个操作数加入后缀表达式中,注意是引用传递dest.push_back(ReadIntNum(src, i));i--; //由于后面会进行++操作,这里要保持在读到的最后一个数字位上} else if (IsLeftBrac(src[i])) { //如果遇到左括号直接入栈opStack.push(src[i]);} else if (IsRightBrac(src[i])) { //如果遇到右括号将栈顶元素出栈,加入后缀表达式,直到遇到左括号,将这个左括号弹出while (opStack.top()!= MatchBrac(src[i])) {temp += opStack.top();dest.push_back(temp);opStack.pop();temp = "";}opStack.pop(); //弹出( [ {} else if (IsOprand(src, i)){  //如果遇到的是操作符,将站定优先级大于等于该操作符的元素出栈,加入后缀表达式while ((!opStack.empty()) && (GetPri(opStack.top()) >= GetPri(src[i])) &&!IsLeftBrac(opStack.top())) {  //直到遇到左括号或栈为空(为空的判断优先)temp += opStack.top();dest.push_back(temp);opStack.pop();temp = "";}opStack.push(src[i]); //将当前字符入栈}i++;}while (!opStack.empty()) {temp += opStack.top();dest.push_back(temp);opStack.pop();temp = "";}return dest;
}

完整代码:

#include <iostream>
#include <vector>
#include <stack>
#include <cctype>
#include <cstdlib>
using namespace std;bool IsLeftBrac(char ch)
{return (ch == '(' || ch == '[' || ch == '{');
}bool IsRightBrac(char ch)
{return (ch == ')' || ch == ']' || ch == '}');
}char MatchBrac(char ch)
{char temp;switch (ch) {case ')':temp = '(';break;case ']':temp = '[';break;case '}':temp = '{';break;default:temp = '\0';break;  }return temp;
}bool IsOprand(string src, int idx)
{bool isSign = (src[idx] == '+' || src[idx] == '-' || src[idx] == '*' || src[idx] == '/');bool isValid = isdigit(src[idx - 1]) || IsRightBrac(src[idx - 1]); //运算符的左侧只能是数字或者右括号return (isSign && isValid);
}string ReadIntNum(string src, int &idx)
{string value = "";if (src[idx - 1] == '-' && !IsOprand(src, idx - 1)){ //当数字的前一个是'-'且这个'-'不能作为运算符时就作为负号使用value += '-';}while (isdigit(src[idx])) {value += src[idx++];}return value;}int CalFunc(int a, char op, int b)
{int ret = 0;switch (op) {case '+':ret = a + b;break;case '-':ret = a - b;break;case '*':ret = a * b;break;case '/':ret = a / b;break;default:ret = 0;break;}return ret;
}int GetPri(char ch)
{int pri = 0;switch (ch) {case '+':case '-':pri = 1;break;case '*':case '/':pri = 2;break;default:pri = 0;break;}return pri;
}int GetExprValue(vector<string> srcVec)   //根据后缀表达式求值
{stack<int> temp;char op = '\0';int a = 0;int b = 0;for (int i = 0; i < srcVec.size(); i++) {op = srcVec[i][srcVec[i].length() - 1];if (isdigit(op)) {temp.push(atoi(srcVec[i].c_str())); //如果是数字则直接入栈} else {a = temp.top();                     //否则从栈中取出两个操作数进行计算(注意操作数的左右顺序)temp.pop();                            //然后将计算的值入栈b = temp.top();temp.pop();temp.push(CalFunc(b, op, a));}}return temp.top();
}vector<string> GetSufix(string src)
{vector<string> dest;stack<char> opStack;int i = 0;string temp = "";while (i < src.length()) {if (isdigit(src[i])) {  //如果遇到数字就读取一个操作数加入后缀表达式中,注意是引用传递dest.push_back(ReadIntNum(src, i));i--; //由于后面会进行++操作,这里要保持在读到的最后一个数字位上} else if (IsLeftBrac(src[i])) { //如果遇到左括号直接入栈opStack.push(src[i]);} else if (IsRightBrac(src[i])) { //如果遇到右括号将栈顶元素出栈,加入后缀表达式,直到遇到左括号,将这个左括号弹出while (opStack.top()!= MatchBrac(src[i])) {temp += opStack.top();dest.push_back(temp);opStack.pop();temp = "";}opStack.pop(); //弹出( [ {} else if (IsOprand(src, i)){  //如果遇到的是操作符,将站定优先级大于等于该操作符的元素出栈,加入后缀表达式while ((!opStack.empty()) && (GetPri(opStack.top()) >= GetPri(src[i])) &&!IsLeftBrac(opStack.top())) {  //直到遇到左括号或栈为空(为空的判断优先)temp += opStack.top();dest.push_back(temp);opStack.pop();temp = "";}opStack.push(src[i]); //将当前字符入栈}i++;}while (!opStack.empty()) {temp += opStack.top();dest.push_back(temp);opStack.pop();temp = "";}return dest;
}int main()
{string src;while (cin >> src) {vector<string> ret = GetSufix(src);cout << GetExprValue(ret) << endl;}return 0;
}

万能计算器——中缀表达式转换成后缀表达式(C++实现)【可以计算小数和负数】相关推荐

  1. 使用栈实现中缀表达式转换成后缀表达式并计算结果(逆波兰计算器)

    一.中缀表达式转换成后缀表达式 具体步骤如下: 1.初始化栈stack(暂时存放运算符)以及集合list(存放后缀表达式) 2.从左向右扫描中缀表达式 3.当前元素为数字时,直接添加到list中 4. ...

  2. c语言表达式的后缀,中缀表达式转换成后缀表达式C语言程序(一)

    逆波兰表达式(Reverse Polish Notation)又叫后缀表达式.它是一种非常的表达式,可以将复杂的表达式转换成可以依靠简单的操作得到结果的表达.下面这段C语言即是用于实现将中缀表达式转换 ...

  3. 表达式转换成后缀表达式进行计算

    这是编译原理课上的一个实验,要将输入的表达式转换成后缀表达式,然后进行计算.当时写的程序有错误,改了两天,没有了错误,但还是有些表达式计算不出正确的结果,实在不想改了,等什么时候心情好了,再看看吧. ...

  4. 中缀表达式转换成后缀表达式

    中缀表达式就是我们正常工作中写的表达式,如 a+(b-c)*d ,编译系统将中缀表达式改写 abc-d*+,这种运算符在操作数后面称为后缀表达式(也称逆波兰表达式). 如何实现转换的呢?这里做一下自己 ...

  5. Java 将中缀表达式转换成后缀表达式

    使用堆栈进行表达式的堆栈将中缀(Infix)表达式转换成后缀(postfix)表达式 完整代码 import java.io.IOException;public class InToPost {pr ...

  6. java中的後綴表達式_求Java堆栈,将中缀算术表达式转换成后缀表达式。

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 package lab2.lang; import java.util.ArrayList; import java.util.HashMap; impo ...

  7. 中缀表达式转换成后缀表达式(只适用于加减乘除运算)

    1 #include <iostream> 2 #include <stack> 3 #include <cctype> 4 5 using namespace s ...

  8. java 中缀算术表达式转换成后缀表达式_求Java堆栈,将中缀算术表达式转换成后缀表达式。...

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 package lab2.lang; import java.util.ArrayList; import java.util.HashMap; impo ...

  9. (中缀)表达式转换成前缀表达式、后缀表达式

    认识前缀.中缀.后缀表达式: 一般我们平时用的计算式都是中缀表达式,因为符号都是在操作数的中间的.相对应的符号在操作数后面的就叫后缀表达式(也称逆波兰式),符号在操作数前面的就叫前缀表达式(也称波兰式 ...

最新文章

  1. 软件项目随着数据量的不断增加,有什么优化方案么?
  2. Hi3516A开发--常用指令和根文件目录详解
  3. c语言程序中注释的格式化,格式化C语言命令indent
  4. mybatis 插入数据后返回自增id
  5. php生日计算年龄,php根据生日计算年龄的方法
  6. NOI数学:莫比乌斯变换
  7. Linux系统通过FTP进行文档基本操作【华为云分享】
  8. excel去重_Python 轻松搞定 Excel 常用的 20 个操作
  9. oracle表空间查询维护命令大全之二(undo表空间)
  10. SpringBoot2.0.0启动流程
  11. openstack nova ×××
  12. mysql如何更改文件所有者sa_Mssql Server2005中更改sa的用户名的多种方法
  13. 关于网狐游戏vs2003移植到vs2013
  14. 设置div背景色为半透明
  15. e900v21e 装第三方_创维e900v21e刷机包
  16. UITableView 部分方法详解
  17. Python在线办公系统毕业设计源码071116
  18. #医疗算法招聘:【医学影像AI公司-图像算法工程师】(招2人)
  19. 简单理解Hadoop(Hadoop是什么、如何工作)
  20. [医学图像分割综述] Medical Image Segmentation Using Deep Learning: A Survey

热门文章

  1. 智慧水务平台解决方案包括哪些内容
  2. vue项目新闻消息向上滚动案例
  3. 【Web前端HTML5CSS3】16-过渡与动画
  4. 路科验证MCDF_svlab3笔记
  5. iOS开发过程中使用Core Data应避免的十个错误
  6. 【msvcp140.dll怎么下载】吃鸡msvcp140.dll丢失的解决方法
  7. (转)Burp Suite 的一些插件
  8. Knapsack Problem(0-1背包问题)
  9. Java反射面试总结(一)
  10. Jsp中htmlEscape=false是什么意思