C++代码实现逆波兰式

 更新时间:2020年11月01日 10:18:23   作者:ronnie88597  
这篇文章主要为大家详细介绍了C++代码实现逆波兰式,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

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;
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • Qt编写自定义控件实现抽奖转盘

    Qt编写自定义控件实现抽奖转盘

    这篇文章主要为大家详细介绍了Qt编写自定义控件实现抽奖转盘,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-06-06
  • 对称矩阵的压缩储存讲解

    对称矩阵的压缩储存讲解

    今天小编就为大家分享一篇关于对称矩阵的压缩储存讲解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-02-02
  • 深入Windows下的回车是回车换行(\r\n)还是换行回车(\n\r)的详解

    深入Windows下的回车是回车换行(\r\n)还是换行回车(\n\r)的详解

    本篇文章对Windows下的回车是回车换行(\r\n)还是换行回车(\n\r)进行了详细的分析介绍,需要的朋友参考下
    2013-05-05
  • C++实现通讯录系统项目实战

    C++实现通讯录系统项目实战

    这篇文章主要为大家详细介绍了C++实现通讯录系统项目实战,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-06-06
  • C++基础入门教程(八):函数指针

    C++基础入门教程(八):函数指针

    这篇文章主要介绍了C++基础入门教程(八):函数指针,本文讲解了函数原型和函数定义、const限定符与指针、函数的指针参数、为什么要使用指针参数等内容,需要的朋友可以参考下
    2014-11-11
  • C语言实现弹跳小球动画

    C语言实现弹跳小球动画

    这篇文章主要为大家详细介绍了C语言实现弹跳小球动画,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-05-05
  • 详解C++编程中表达式的语义与计算顺序

    详解C++编程中表达式的语义与计算顺序

    这篇文章主要介绍了C++编程中表达式的语义与计算顺序,是C++入门学习中的基础知识,需要的朋友可以参考下
    2016-01-01
  • 详解Matlab实现动态表白图的绘制

    详解Matlab实现动态表白图的绘制

    这篇文章主要利用Matlab实现绘制独特的表白动图,文中的示例代码讲解详细,对我们学习Matlab有一定的帮助,感兴趣的小伙伴可以了解一下
    2022-05-05
  • C语言三子棋游戏的简单设计

    C语言三子棋游戏的简单设计

    这篇文章主要为大家详细介绍了C语言三子棋游戏的简单设计,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-10-10
  • C语言中#pragma pack(1)的用法与注意点

    C语言中#pragma pack(1)的用法与注意点

    #pragma用于指示编译器完成一些特定的动作,下面这篇文章主要给大家介绍了关于C语言中#pragma pack(1)的用法与注意点的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2023-02-02

最新评论