C++代碼實(shí)現(xiàn)逆波蘭式
100行以內(nèi)C++代碼實(shí)現(xiàn)逆波蘭式
逆波蘭式(Reverse Polish notation,RPN,或逆波蘭記法),也叫后綴表達(dá)式(將運(yùn)算符寫在操作數(shù)之后)。
算術(shù)表達(dá)式轉(zhuǎn)逆波蘭式例子:

逆波蘭式整體的算法流程圖如下:

下面給出我基于C++ 語言對逆波蘭式算法的實(shí)現(xiàn)代碼,值得注意的是:
1、算法中對操作數(shù),僅支持一個(gè)字符的字母或數(shù)字的操作數(shù),如:x,y,j,k,3,7等;如果要支持多個(gè)字符的操作數(shù),如:var1,3.14等。需要讀者自己擴(kuò)展對算術(shù)表達(dá)式操作數(shù)的分詞部分的代碼。
2、為了為了增加轉(zhuǎn)換后的逆波蘭表達(dá)式的可讀性,我在每個(gè)操作數(shù)和操作符輸出時(shí)后面追加了一個(gè)空格。
代碼如下:
/// 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;
}
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
QT實(shí)現(xiàn)QML側(cè)邊導(dǎo)航欄的最簡方法
本文主要介紹了QT實(shí)現(xiàn)QML側(cè)邊導(dǎo)航欄的最簡方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-06-06
C++ explicit關(guān)鍵字的應(yīng)用方法詳細(xì)講解
C++ explicit關(guān)鍵字用來修飾類的構(gòu)造函數(shù),表明該構(gòu)造函數(shù)是顯式的,既然有"顯式"那么必然就有"隱式",那么什么是顯示而什么又是隱式的呢?下面就讓我們一起來看看這方面的知識吧2013-09-09
詳解C++中vector的理解以及模擬實(shí)現(xiàn)
vector是表示可變大小數(shù)組的序列容器。這篇文章主要為大家詳細(xì)介紹了vector的理解以及模擬實(shí)現(xiàn),文中的示例代碼講解詳細(xì),感興趣的可以了解一下2023-03-03
C++中String類的常用接口函數(shù)總結(jié)
這篇文章主要介紹了C++中Stirng類的常用接口函數(shù),文中有詳細(xì)的代碼示例供大家參考,對我們學(xué)習(xí)C++有一定的幫助,感興趣的同學(xué)可以跟著小編一起來學(xué)習(xí)2023-06-06

