100 行 C++ 代码中的逆波兰语
反向波兰表示法(RPN,或反向波兰表示法),也称为后缀表达式(在操作数后写入运算符)。
算术表达式反转波兰示例:
逆波兰整体的算法流程图如下:
以下是我基于C++语言的逆波兰算法的实现代码。值得一提的是:
1、对于算法中的操作数逆波兰表示法 c语言,只支持一个字符的字母数字操作数,如:x、y、j、k、3、7等;如果要支持多字符操作数,例如:var1、3.14 等。算术表达式操作数的分词部分的代码由读者扩展。
2、为了增加转换后的逆波兰表达式的可读性逆波兰表示法 c语言,我在每个操作数和运算符输出中附加了一个空格。
代码显示如下:
/// file: ReversePolishNotation.h #include #include class ReversePolishNotation { private: std::string _expr; unsigned _idx; std::stack _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 #include #include "ReversePolishNotation.h" #include #include 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 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 <>>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; }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持Scripting Home。
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 欧资源网