C++栈实现逆波兰式的应用

目录
  • 一.定义
  • 二.逆波兰式的意义
  • 三.逆波兰式的实现
    • 1.方法
    • 2.代码实现

一.定义

逆波兰式,又称后缀表达式,指的是操作符在其所控制的操作数后面的表达式。
举个例子,1 + 2 * 3 - 4这个表达式是我们熟悉的中缀表达式,那么其所对应的后缀表达式为:1 2 3 * + 4 -
再来个复杂的例子:1 * (2 + 3) / 5 - 4 / 2其对应的后缀表达式为:1 2 3 + * 5 / 4 2 / -(其中括号由于只是提升表达式优先级的作用,因此不放入后缀表达式中)。

二.逆波兰式的意义

为什么要将看似简单的中缀表达式转换为复杂的逆波兰式,原因就在于这个简单是相对我们人类的思维结构来说的,对计算机而言中序表达式是非常复杂的结构。相对的,逆波兰式在计算机看来却是比较简单易懂的结构。因为计算机普遍采用的内存结构是栈式结构,它执行先进后出的顺序。

三.逆波兰式的实现

1.方法

(1)中缀表达式转化为后缀表达式

对于给出的中缀表达式,如何将其转化为后缀表达式呢?
第一,若遇到操作数则直接输出/存储。
第二,遇到操作符,若此时栈为空或者操作符优先级高于栈顶,则入栈。
第三,若操作符的优先级低于或者等于栈顶,则出栈直至栈空或者优先级低于该操作符。
第四,遇到'(',其后的所有操作符(直至遇到')')按上述操作入栈或出栈;当遇到')‘时,将'('顶上的所有操作符出栈。

(2)由后缀表达式计算结果

第一,遇到操作数则入栈。
第二,遇到操作符则将栈顶的两个操作数出栈,其中第一个数为右操作数,第二个数为左操作数。
第三,计算结果并将计算的结果入栈。
第四,最后栈顶的结果即为所计算的结果。

2.代码实现

#include <iostream>
#include <string>
#include <stack>
#include <vector>
using namespace std;

string trans(string& s)
{
	string operand;
	stack<char> Operator;
	int flag = 0;//记录括号优先级
	for (const auto& e : s)
	{
		if (e == '(')
		{
			Operator.push(e);
			flag = 1;
			continue;
		}
		if (e == ')')
		{
			flag = 0;
			while (Operator.top() != '(')
			{
				operand.push_back(Operator.top());
				Operator.pop();
			}
			Operator.pop();
			continue;
		}
		//操作符
		if (e == '+' || e == '-' || e == '*' || e == '/')
		{
			if (flag == 1)
			{
				if (Operator.top() == '(')
				{
					Operator.push(e);

				}
				else if ((e == '*' || e == '/') && (Operator.top() == '+' || Operator.top() == '-'))
				{
					Operator.push(e);
				}
				else//操作符的优先级低于或等于栈顶操作符则出栈,直至遇到'('
				{
					while (Operator.top() != '(')
					{
						operand.push_back(Operator.top());
						Operator.pop();
					}
					Operator.push(e);
				}
			}
			else if (Operator.empty())//栈空就入栈
			{
				Operator.push(e);
			}
			//操作符的优先级高于栈顶操作符,入栈
			else if ((e == '*' || e == '/') && (Operator.top() == '+' || Operator.top() == '-'))
			{
				Operator.push(e);
			}
			else//操作符的优先级低于或等于栈顶操作符则出栈,直至栈空或者优先级高于栈顶操作符
			{
				while (!Operator.empty())
				{
					operand.push_back(Operator.top());
					Operator.pop();
				}
				Operator.push(e);
			}
		}
		//操作数
		else
		{
			operand.push_back(e);
		}
	}
	while (!Operator.empty())
	{
		operand.push_back(Operator.top());
		Operator.pop();
	}
	return operand;
}

int evalRPN(const string& s)
{
	stack<char> operand;
	int left = 0, right = 0;
	for (const auto& e : s)
	{
		if (e == '+' || e == '-' || e == '*' || e == '/')
		{
			switch (e)
			{
			case '+':
				right = operand.top();
				operand.pop();
				left = operand.top();
				operand.pop();
				operand.push(left + right);
				break;
			case '-':
				right = operand.top();
				operand.pop();
				left = operand.top();
				operand.pop();
				operand.push(left - right);
				break;
			case '*':
				right = operand.top();
				operand.pop();
				left = operand.top();
				operand.pop();
				operand.push(left * right);
				break;
			case '/':
				right = operand.top();
				operand.pop();
				left = operand.top();
				operand.pop();
				operand.push(left / right);
				break;
			}
		}
		else//操作数
		{
			operand.push(e - '0');
		}
	}
	return operand.top();
}

int RPN(const string& str)
{
	//1.中缀表达式转化为后缀表达式
	string s(str);
	s = trans(s);
	//2.后缀表达式计算答案
	return evalRPN(s);
}

int main()
{
	string s("1*(2*3+5)/5-4/2");
	int ret = RPN(s);
	cout << "ret:" << ret << endl;
	return 0;
}

结果:

到此这篇关于C++栈实现逆波兰式的应用的文章就介绍到这了,更多相关C++ 逆波兰式内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • C++代码实现逆波兰式

    100行以内C++代码实现逆波兰式 逆波兰式(Reverse Polish notation,RPN,或逆波兰记法),也叫后缀表达式(将运算符写在操作数之后). 算术表达式转逆波兰式例子: 逆波兰式整体的算法流程图如下: 下面给出我基于C++ 语言对逆波兰式算法的实现代码,值得注意的是: 1.算法中对操作数,仅支持一个字符的字母或数字的操作数,如:x,y,j,k,3,7等:如果要支持多个字符的操作数,如:var1,3.14等.需要读者自己扩展对算术表达式操作数的分词部分的代码. 2.为了为了增加

  • C++实现逆波兰式

    (a+b)c的逆波兰式为ab+c,假设计算机把ab+c按从左到右的顺序压入栈中,并且按照遇到运算符就把栈顶两个元素出栈,执行运算,得到的结果再入栈的原则来进行处理,那么ab+c的执行结果如下: 1)a入栈(0位置) 2)b入栈(1位置) 3)遇到运算符"+",将a和b出栈,执行a+b的操作,得到结果d=a+b,再将d入栈(0位置) 4)c入栈(1位置) 5)遇到运算符"",将d和c出栈,执行dc的操作,得到结果e,再将e入栈(0位置) 经过以上运算,计算机就可以得到

  • C++栈实现逆波兰式的应用

    目录 一.定义 二.逆波兰式的意义 三.逆波兰式的实现 1.方法 2.代码实现 一.定义 逆波兰式,又称后缀表达式,指的是操作符在其所控制的操作数后面的表达式. 举个例子,1 + 2 * 3 - 4这个表达式是我们熟悉的中缀表达式,那么其所对应的后缀表达式为:1 2 3 * + 4 -. 再来个复杂的例子:1 * (2 + 3) / 5 - 4 / 2其对应的后缀表达式为:1 2 3 + * 5 / 4 2 / -(其中括号由于只是提升表达式优先级的作用,因此不放入后缀表达式中). 二.逆波兰式

  • PHP使用逆波兰式计算工资的方法

    本文实例讲述了PHP使用逆波兰式计算工资的方法.分享给大家供大家参考.具体如下: 将一个普通的中序表达式转换为逆波兰表达式的一般算法是: 首先需要分配2个栈,一个作为临时存储运算符的栈S1(含一个结束符号),一个作为输入逆波兰 式的栈S2(空栈),S1栈可先放入优先级最低的运算符#,注意,中缀式应以此最低优先级的运算符结束.可指定其他字符,不一定非#不可.从中缀式的左端 开始取字符,逐序进行如下步骤: (1)若取出的字符是操作数,则分析出完整的运算数,该操作数直接送入S2栈:若取出的是运算符,并

  • C语言实现逆波兰式实例

    复制代码 代码如下: #include<stdio.h>#include<string.h> typedef struct{char s[20][20];int top;}SQ; void copystr(char *a,char *b){    int i=0;    do    {        b[i]=a[i];        i++;    }    while(a[i]!='\0');    b[i]='\0';} void voidSQ(SQ *s){    s-&g

  • 逆波兰计算器(Java实现)

    之前的一篇博客中,讲的是用栈实现了中缀表达式的简易计算器,对于我们人来讲,中缀表达式是一种比较直观,而且非常好计算的一种形式,但对于计算器来讲,非常的难去看懂.所以,下面我讲下逆波兰计算器的Java实现. 逆波兰式(后缀表达式) 逆波兰表达式又叫做后缀表达式.逆波兰表示法是波兰逻辑学家J・卢卡西维兹(J・ Lukasewicz)于1929年首先提出的一种表达式的表示方法 [1]  .后来,人们就把用这种表示法写出的表达式称作"逆波兰表达式".逆波兰表达式把运算量写在前面,把算符写在后面

  • Java编程实现逆波兰表达式代码示例

    逆波兰表达式 定义:传统的四则运算被称作是中缀表达式,即运算符实在两个运算对象之间的.逆波兰表达式被称作是后缀表达式,表达式实在运算对象的后面. 逆波兰表达式: a+b ---> a,b,+ a+(b-c) ---> a,b,c,-,+ a+(b-c)*d ---> a,b,c,-,d,*,+ a+d*(b-c)--->a,d,b,c,-,*,+ a=1+3 ---> a=1,3 + http=(smtp+http+telnet)/1024 写成什么呢? http=smtp,

  • Python实现处理逆波兰表达式示例

    本文实例讲述了Python实现处理逆波兰表达式.分享给大家供大家参考,具体如下: 中文名: 逆波兰表达式 外文名: Reverse Polish Notation 别名: 后缀表达式 逆波兰表达式又叫做后缀表达式.在通常的表达式中,二元运算符总是置于与之相关的两个运算对象之间,这种表示法也称为中缀表示.波兰逻辑学家J.Lukasiewicz于1929年提出了另一种表示表达式的方法,按此方法,每一运算符都置于其运算对象之后,故称为后缀表示.这个知识点在数据结构和编译原理这两门课程中都有介绍.它的优

  • C++代码实现逆波兰表达式

    本文实例为大家分享了C++实现逆波兰表达式的具体代码,供大家参考,具体内容如下 当我们输入一个数学表达式,是中缀表达式,我们首先转换为后缀表达式(逆波兰表达式),然后再进行求值. 在<大话数据结构>的104-100页有详细的介绍,下面是我理解之后的代码实现. 代码思路: (1)首先对输入的中缀表达式合法性进行判断,bool isStringLegal(const char* str); 函数实现. (2)然后把中缀表达式转换为后缀表达式. (3)根据后缀表达式求出结果,double getTh

  • C++实现LeetCode(150.计算逆波兰表达式)

    [LeetCode] 150.Evaluate Reverse Polish Notation 计算逆波兰表达式 Evaluate the value of an arithmetic expression in Reverse Polish Notation. Valid operators are +, -, *, /. Each operand may be an integer or another expression. Note: Division between two integ

随机推荐