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

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

下面給出我基于C++ 語(yǔ)言對(duì)逆波蘭式算法的實(shí)現(xiàn)代碼,值得注意的是:
1、算法中對(duì)操作數(shù),僅支持一個(gè)字符的字母或數(shù)字的操作數(shù),如:x,y,j,k,3,7等;如果要支持多個(gè)字符的操作數(shù),如:var1,3.14等。需要讀者自己擴(kuò)展對(duì)算術(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 == "/";
}
/// ---測(cè)試代碼---
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;
}
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
使用C++實(shí)現(xiàn)簡(jiǎn)單的文章生成器
這篇文章主要為大家詳細(xì)介紹了鵝湖使用C++實(shí)現(xiàn)簡(jiǎn)單的狗屁不通文章生成器,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,有需要的小伙伴可以了解下2024-03-03
C語(yǔ)言模擬實(shí)現(xiàn)密碼輸入的示例代碼
本文主要介紹了C語(yǔ)言模擬實(shí)現(xiàn)密碼輸入的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-02-02
C++生成格式化的標(biāo)準(zhǔn)字符串實(shí)例代碼
這篇文章主要給大家介紹了關(guān)于C++生成格式化的標(biāo)準(zhǔn)字符串的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用C++具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-09-09
C++實(shí)現(xiàn)圖書管理系統(tǒng)源碼
這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)圖書管理系統(tǒng)源碼,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03
詳解C++中new運(yùn)算符和delete運(yùn)算符的使用
這篇文章主要介紹了C++中new運(yùn)算符和delete運(yùn)算符的使用,文章來(lái)自于微軟開發(fā)者文檔,因而根據(jù)Visual C++的一些特性來(lái)進(jìn)行講解,需要的朋友可以參考下2016-01-01
C語(yǔ)言實(shí)現(xiàn)紅黑樹詳細(xì)步驟+代碼
大家好,本篇文章主要講的是C語(yǔ)言實(shí)現(xiàn)紅黑樹詳細(xì)步驟+代碼,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話記得收藏一下2022-01-01
C++標(biāo)準(zhǔn)庫(kù)中sstream與strstream的區(qū)別詳細(xì)解析
以下是對(duì)C++標(biāo)準(zhǔn)庫(kù)中sstream與strstream的區(qū)別進(jìn)行了詳細(xì)的分析介紹,需要的朋友可以過(guò)來(lái)參考下2013-09-09
C++關(guān)于/2和>>1的區(qū)別說(shuō)明
這篇文章主要介紹了C++關(guān)于/2和>>1的區(qū)別說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-07-07

