IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 算数表达式的中序和后序的转换与计算 -> 正文阅读

[C++知识库]算数表达式的中序和后序的转换与计算

? ? ? ?常见的四则混合运算表达式,中缀表达式便于人的理解,但后序表达式更方便计算机的运算(如二叉树、堆栈的方法计算)。本文主要谈论的重点是将算术表达式的“中序表达式”转换为“后序表达式”,并根据后序表达式得到算数表达式的值。

一、中序表达式-->后序表达式(堆栈)

1、举例:

2、具体实现的算法步骤(中序->后序(infix->postfix)):

2.1)从左到右读取中序表达式infix_express中的每个字符;

2.2)如果读入的字符为操作数(a~z/A~Z),则直接输出到后序法表达式postfix_express中;

2.3)如果遇到'(',则弹出堆栈内的运算符,知道弹出到一个')',两者抵消;

?????'('的优先级在堆栈中,比任何运算符都小;但在堆栈外却是优先级最高的运算符;

2.4)将准备进入堆栈中的“外部运算符”与“栈顶的运算符”进行优先级比较,高于则外部运算符压入栈中;低于或等于则将栈中的元素逐个从栈顶弹出,直到外部运算符的优先级高于栈顶的运算符或栈为空时,将外部运算符压入栈;

2.5)读取完中序表达式后,如果堆栈不为空,则将其内部的运算符从栈顶逐个弹出并写在postfix_express的尾部;

注:(部分运算符)在栈中的优先级的排序:'^'、'*'? '/'、'+' '-'、'('等;

3、代码实现:

#include <iostream>
#include<stack>     // use std::stack for Stack operations
#include<string>
using namespace std;

/* C++ implementation to convert infix expression to postfix*/

//Function to return precedence of operators
int precede(char c)
{
	if (c == '^') { return 3; }
	else if (c == '*' || c == '/') { return 2; }
	else if (c == '+' || c == '-') { return 1; }
	else if (c == '(' ) { return -1; }
    else { return -1; }
}

// convert infix expression to postfix expression
string infixToPostfix(string str)
{
	std::stack<char> stack_operator;   // 用来存放运算符
	stack_operator.push('#');      // 栈空的标识符

	int len = str.length();     // 输入的中序表达式的长度

	string output_postfix;    // 用来存放输出的后序表达式postfix
	for (int i = 0; i < len; i++)
	{
		if (str[i] != ' ')   // 消除字符串中,空格的影响
		{
			// If the scanned character is an operand(操作数), add it to output string
			if ((str[i] >= 'a' && str[i] <= 'z') || (str[i] >= 'A' && str[i] <= 'Z'))
			{
				output_postfix += str[i];
			}
			// If the scanned character is an '(', push it to the stack
			else if (str[i] == '(')
			{
				stack_operator.push('(');
			}
			// If the scanned character is an ')', pop and to output string from the stack until an ‘(‘ is encountered.
			else if (str[i] == ')')
			{
				while (stack_operator.top() != '#' && stack_operator.top() != '(')
				{
					char ch = stack_operator.top();
					stack_operator.pop();
					output_postfix += ch;
				}

				// 此种情况是,(一个操作数),故直接将栈中的'('弹出
				if (stack_operator.top() == '(')
				{
					stack_operator.pop();
				}
			}
			// If an operator is scanned
			else
			{
				while (stack_operator.top() != '#' && precede(str[i]) <= precede(stack_operator.top()))
				{
					char ch = stack_operator.top();
					stack_operator.pop();
					output_postfix += ch;
				}
				stack_operator.push(str[i]);
			}
		}
	}
	// Pop all the remaining elements from the stack
	while (stack_operator.top() != '#')
	{
		char ch = stack_operator.top();
		stack_operator.pop();
		output_postfix += ch;
	}
	return output_postfix;
}

int main()
{
	string infix_express = "a+b*c/h+((d^i)*e+f)*g";
	cout <<  "infix:" << infix_express << endl;

	string postfix_express = infixToPostfix(infix_express);
	cout << "postfix:" << postfix_express << endl;

	return 0;
}

二、中序表达式-->后序表达式(二叉树)

待后序学习

三、将中序表达式转换成后序表达式,并计算结果

代码分析:先利用前面提到的将中序表达式转换为后序表达式;接下来,后序表达式可以直接在计算机上运算,使用循环读取表达式中的每个字符并转换成整型压入栈中,当读到运算符时从栈顶pop两个整型数字,运算后重新将结果压入栈中,知道循环结束,输出结果;

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

string infixToPostfix(string str)
{
	std::stack<char> stack_operator;   // 用来存放运算符
	stack_operator.push('#');      // 栈空的标识符

	int len = str.length();     // 输入的中序表达式的长度

	string output_postfix;    // 用来存放输出的后序表达式postfix
	for (int i = 0; i < len; i++)
	{
		// If the scanned character is an operand(操作数), add it to output string
		if (str[i] != ' ')
		{
			if (str[i] >= '0' && str[i] <= '9')
			{
				output_postfix += str[i];
			}
			// If the scanned character is an '(', push it to the stack
			else if (str[i] == '(')
			{
				stack_operator.push('(');
			}
			// If the scanned character is an ')', pop and to output string from the stack until an ‘(‘ is encountered.
			else if (str[i] == ')')
			{
				while (stack_operator.top() != '#' && stack_operator.top() != '(')
				{
					char ch = stack_operator.top();
					stack_operator.pop();
					output_postfix += ch;
				}

				// 此种情况是,(一个操作数),故直接将栈中的'('弹出
				if (stack_operator.top() == '(')
				{
					stack_operator.pop();
				}
			}
			// If an operator is scanned
			else
			{
				while (stack_operator.top() != '#' && precede(str[i]) <= precede(stack_operator.top()))
				{
					char ch = stack_operator.top();
					stack_operator.pop();
					output_postfix += ch;
				}
				stack_operator.push(str[i]);
			}
		}
	}

	// Pop all the remaining elements from the stack
	while (stack_operator.top() != '#')
	{
		char ch = stack_operator.top();
		stack_operator.pop();
		output_postfix += ch;
	}
	return output_postfix;
}

int calcPostfix(string str)
{
	std::stack<int> stack_operand;   // 用来存放操作数

	int len = str.length();
	for (int i = 0; i < len; i++)
	{
		if (str[i] != ' ')
		{
			if (str[i] >= '0' && str[i] <= '9')
			{
				stack_operand.push((int)str[i] - 48);      // 将字符型数字,转换为整型数字
			}
			else
			{
				int data1 = stack_operand.top();
				stack_operand.pop();
				int data2 = stack_operand.top();
				stack_operand.pop();
				if (str[i] == '+')
				{
					stack_operand.push(data1 + data2);
				}
				else if (str[i] == '-')
				{
					stack_operand.push(data1 - data2);
				}
				else if (str[i] == '*')
				{
					stack_operand.push(data1 * data2);
				}
				else if (str[i] == '/')
				{
					stack_operand.push((int)data1 / data2);
				}
				else if (str[i] == '/')
				{
					stack_operand.push(data1 ^ data2);
				}
			}
		}
	}

	return stack_operand.top();
}

int main()
{
	string infix_express = "2*(3+4) + 5/6";
	string postfix_express = infixToPostfix(infix_express);
	cout << "postfix:" << postfix_express << endl;

	int result = calcPostfix(postfix_express);
	cout << result << endl;
}

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-04-30 08:30:43  更:2022-04-30 08:31:07 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 22:11:45-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码