时间:2021-05-20
100行以内C++代码实现逆波兰式
逆波兰式(Reverse Polish notation,RPN,或逆波兰记法),也叫后缀表达式(将运算符写在操作数之后)。
算术表达式转逆波兰式例子:
逆波兰式整体的算法流程图如下:
下面给出我基于C++ 语言对逆波兰式算法的实现代码,值得注意的是:
1、算法中对操作数,仅支持一个字符的字母或数字的操作数,如:x,y,j,k,3,7等;如果要支持多个字符的操作数,如:var1,3.14等。需要读者自己扩展对算术表达式操作数的分词部分的代码。
2、为了为了增加转换后的逆波兰表达式的可读性,我在每个操作数和操作符输出时后面追加了一个空格。
代码如下:
/// file: ReversePolishNotation.h#include <string>#include <stack>class ReversePolishNotation {private: std::string _expr; unsigned _idx; std::stack<std::string> _stk;public: ReversePolishNotation(const std::string &expr); std::string nextWord(); std::string operator()(); static int getOpPriority(const std::string &word); bool isWord(const std::string &word); bool isOperator(const std::string &word);};/// file: ReversePolishNotation.cpp#include <iostream>#include <cassert>#include "ReversePolishNotation.h"#include <cctype>#include <sstream>using std::cout;using std::endl;ReversePolishNotation::ReversePolishNotation( const std::string &expr) : _idx(0), _expr(expr) {}std::string ReversePolishNotation::nextWord() { if (_idx >= _expr.length()) { return ""; } return _expr.substr(_idx++, 1);}std::string ReversePolishNotation::operator()() { std::stringstream outExpr; std::string word; std::string topElem; while (true) { word = nextWord(); if (isWord(word)) { outExpr << word << " "; } else if (isOperator(word)) { if (_stk.empty() || _stk.top() == "(") { _stk.push(word); continue; } topElem = _stk.top(); while (getOpPriority(topElem) > getOpPriority(word)) { outExpr << topElem << " "; _stk.pop(); if (_stk.empty()) { break; } topElem = _stk.top(); } _stk.push(word); } else if (word == "(") { _stk.push(word); } else if (word == ")") { while (true) { topElem = _stk.top(); _stk.pop(); if (topElem == "(") { break; } assert(!_stk.empty() && "[E]Expr error. Missing '('."); outExpr << topElem << " "; } } else if (word == "") { while (!_stk.empty()) { topElem = _stk.top(); assert (topElem != "(" && "[E]Expr error. Redundant '('."); outExpr << topElem << " "; _stk.pop(); } break; } else { assert(false && "[W]>>>Can not recognize this word"); } } return outExpr.str();}int ReversePolishNotation::getOpPriority(const std::string &word) { if (word == "+") { return 1; } if (word == "-") { return 1; } if (word == "*") { return 2; } if (word == "/") { return 2; } return 0;}bool ReversePolishNotation::isWord(const std::string &word) { return isalpha(word.c_str()[0]) || isdigit(word.c_str()[0]);}bool ReversePolishNotation::isOperator(const std::string &word) { return word == "+" || word == "-" || word == "*" || word == "/";}/// ---测试代码---int main() { assert(ReversePolishNotation("a+b*c")() == "a b c * + "); assert(ReversePolishNotation("(a+b)*c-(a+b)/e")() == "a b + c * a b + e / - "); assert(ReversePolishNotation("3*(2-(5+1))")() == "3 2 5 1 + - * ");// assert(ReversePolishNotation("3*((2-(5+1))")() == "3 2 5 1 + - * "); // Failed Case: Redundant '('// assert(ReversePolishNotation("3*(?2-(5+1))")() == "3 2 5 1 + - * "); // Failed Case: Can not recognize '?' return 0;}以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
本文实例为大家分享了C语言实现对后缀表达式(逆波兰表达式)的求解代码,供大家参考,具体内容如下逆波兰表达式:逆波兰表达式又叫后缀表达式。它是由相应的语法树的后序
本文实例讲述了Python实现处理逆波兰表达式。分享给大家供大家参考,具体如下:中文名:逆波兰表达式外文名:ReversePolishNotation别名:后缀
本文实例讲述了PHP使用逆波兰式计算工资的方法。分享给大家供大家参考。具体如下:将一个普通的中序表达式转换为逆波兰表达式的一般算法是:首先需要分配2个栈,一个作
本文实例讲述了python实现逆波兰计算表达式的方法。分享给大家供大家参考。具体分析如下:逆波兰表达式又叫做后缀表达式。在通常的表达式中,二元运算符总是置于与之
(a+b)c的逆波兰式为ab+c,假设计算机把ab+c按从左到右的顺序压入栈中,并且按照遇到运算符就把栈顶两个元素出栈,执行运算,得到的结果再入栈的原则来进行处