【数据结构之栈的应用—中缀表达式转后缀表达式、前缀表达式】

文章目录

  • 一、栈的基础概念与实现
    • [1. 栈的基本操作](#1. 栈的基本操作)
    • [2. 栈(C++)](#2. 栈(C++))
  • 二、经典应用
    • [1. 中缀表达式转后缀表达式](#1. 中缀表达式转后缀表达式)
      • [1.1 中缀与后缀表达式介绍](#1.1 中缀与后缀表达式介绍)
      • [1.2 转换步骤](#1.2 转换步骤)
      • [1.3 代码实现(C++)](#1.3 代码实现(C++))
    • [2. 中缀表达式转前缀表达式](#2. 中缀表达式转前缀表达式)
      • [2.1 前缀表达式介绍](#2.1 前缀表达式介绍)
      • [2.2 转换步骤](#2.2 转换步骤)
      • [2.3 代码实现(C++)](#2.3 代码实现(C++))

一、栈的基础概念与实现

栈(Stack)是一种后进先出(LIFO, Last In First Out)的数据结构。它只允许在一端(称为栈顶)进行插入和删除操作。

1. 栈的基本操作

  • Push: 将元素压入栈顶。
  • Pop: 从栈顶弹出元素。
  • Peek/Top: 获取栈顶元素但不删除。

2. 栈(C++)

cpp 复制代码
#include <iostream>
#include <stack>
#include <string>

int main() {
    std::stack<int> s;
    s.push(10);
    s.push(20);
    std::cout << "栈顶元素: " << s.top() << std::endl; // 输出 20
    s.pop();
    std::cout << "栈顶元素: " << s.top() << std::endl; // 输出 10
    return 0;
}

二、经典应用

1. 中缀表达式转后缀表达式

1.1 中缀与后缀表达式介绍

  • 中缀表达式 : 运算符位于两个操作数之间,例如A + B。
  • 后缀表达式 : 运算符位于操作数之后,例如AB+。这种表示法也称为逆波兰表示法(RPN, Reverse Polish Notation)。

1.2 转换步骤

  1. 初始化两个栈 : 运算符栈operatorStack和输出栈outputStack。
  2. 遍历中缀表达式 :
    • 遇到操作数时,将其直接添加到输出栈中。
    • 遇到左括号时,将其压入运算符栈。
    • 遇到右括号时,弹出运算符栈中的运算符并添加到输出栈中,直到遇到左括号为止。
    • 遇到运算符时,将其与运算符栈顶的运算符进行优先级比较。如果栈顶运算符优先级较高或相同,则将栈顶运算符弹出并添加到输出栈,重复此过程,直到栈为空或栈顶运算符优先级较低为止。然后,将当前运算符压入运算符栈。
  3. 将剩余的运算符从运算符栈弹出并添加到输出栈。

1.3 代码实现(C++)

cpp 复制代码
#include <iostream>
#include <stack>
#include <string>

int precedence(char op) {
    if (op == '+' || op == '-') return 1;
    if (op == '*' || op == '/') return 2;
    return 0;
}

std::string infixToPostfix(const std::string &exp) {
    std::stack<char> operatorStack;
    std::string output;

    for (char c : exp) {
        if (isalnum(c)) {
            output += c;  // 操作数直接添加到输出中
        } else if (c == '(') {
            operatorStack.push(c);
        } else if (c == ')') {
            while (!operatorStack.empty() && operatorStack.top() != '(') {
                output += operatorStack.top();
                operatorStack.pop();
            }
            operatorStack.pop();  // 弹出左括号
        } else {
            while (!operatorStack.empty() && precedence(operatorStack.top()) >= precedence(c)) {
                output += operatorStack.top();
                operatorStack.pop();
            }
            operatorStack.push(c);
        }
    }

    while (!operatorStack.empty()) {
        output += operatorStack.top();
        operatorStack.pop();
    }

    return output;
}

int main() {
    std::string infix = "A+(B*C-(D/E^F)*G)*H";
    std::string postfix = infixToPostfix(infix);
    std::cout << "后缀表达式: " << postfix << std::endl;  // 输出 ABC*DEF^/G*-H*+
    return 0;
}

2. 中缀表达式转前缀表达式

2.1 前缀表达式介绍

  • 前缀表达式 : 运算符位于操作数之前,例如+AB。这种表示法也称为波兰表示法(PN, Polish Notation)。

2.2 转换步骤

  1. 反转中缀表达式: 将中缀表达式中的操作数和运算符顺序反转,同时将左括号变为右括号,右括号变为左括号。
  2. 将反转后的中缀表达式转换为后缀表达式。
  3. 反转后缀表达式,得到的即为前缀表达式。

2.3 代码实现(C++)

cpp 复制代码
#include <iostream>
#include <algorithm>
#include <stack>
#include <string>

std::string infixToPrefix(const std::string &exp) {
    std::string reversedExp = exp;
    std::reverse(reversedExp.begin(), reversedExp.end());

    for (char &c : reversedExp) {
        if (c == '(') c = ')';
        else if (c == ')') c = '(';
    }

    std::string reversedPostfix = infixToPostfix(reversedExp);
    std::reverse(reversedPostfix.begin(), reversedPostfix.end());

    return reversedPostfix;
}

int main() {
    std::string infix = "A+(B*C-(D/E^F)*G)*H";
    std::string prefix = infixToPrefix(infix);
    std::cout << "前缀表达式: " << prefix << std::endl;  // 输出 +A-*BC-/^DEF*GH
    return 0;
}
相关推荐
C++ 老炮儿的技术栈1 小时前
不一样的数值交换
数据结构·c++·人工智能·算法·c·csdn开发云
C++ 老炮儿的技术栈1 小时前
main函数之后的调用
c语言·c++·人工智能·qt·mfc·c
知识分享小能手1 小时前
C++ 学习教程,从入门到精通,C++ 友元、异常和其他特性 — 详细知识点(15)
开发语言·c++·学习
hahaha60162 小时前
Shades-of-Gray (SoG) 算法--白平衡算法
人工智能·嵌入式硬件·算法·计算机视觉
ebiobiz2 小时前
极海 APM32 使用 Nimmake 编译指南
c++·python·单片机·嵌入式硬件·mcu
青山木2 小时前
Hot 100 --- 编辑距离
java·数据结构·算法·leetcode·动态规划
朝朝辞暮i2 小时前
C++ 第 26 课:对象、指针与 ->
java·开发语言·c++
夊2 小时前
C语言第十一课:指针(五)
算法
小师兄吃牛肉2 小时前
C语言指针进阶全解析
java·c语言·算法
梦帮科技3 小时前
vLLM / TensorRT-LLM 极限推理:PagedAttention 细粒度物理页表管理与连续批处理(Continuous Batching)实战
数据结构·人工智能·分布式·python·深度学习·算法·vllm