c++ 栈

栈(Stack)是计算机科学中一种非常重要的数据结构,它是一种遵循 后进先出(LIFO, Last In First Out)原则的数据结构,即最后放入栈中的元素最先被取出。

基本操作

  • push: 将元素压入栈顶。

  • pop: 从栈顶弹出元素。

  • toppeek: 获取栈顶元素,但不弹出。

  • isEmpty: 检查栈是否为空。

  • size: 获取栈的大小。

栈的操作通常是基于数组或链表实现的。大多数编程语言都提供了栈的实现(如 C++ STL 中的 std::stack 类)。

栈的实现

使用数组实现一个栈

#include <iostream>
#include <stdexcept>class Stack {
private:int* arr;         // 存储栈元素的数组int capacity;     // 栈的最大容量int topIndex;     // 栈顶索引public:Stack(int cap) : capacity(cap), topIndex(-1) {arr = new int[capacity];}~Stack() {delete[] arr;}// 栈是否为空bool isEmpty() {return topIndex == -1;}// 栈是否已满bool isFull() {return topIndex == capacity - 1;}// 获取栈顶元素int top() {if (isEmpty()) {throw std::out_of_range("Stack is empty");}return arr[topIndex];}// 入栈操作void push(int value) {if (isFull()) {throw std::overflow_error("Stack overflow");}arr[++topIndex] = value;}// 出栈操作void pop() {if (isEmpty()) {throw std::underflow_error("Stack underflow");}--topIndex;}// 获取栈大小int size() {return topIndex + 1;}
};int main() {Stack s(5);s.push(10);s.push(20);s.push(30);std::cout << "Top element: " << s.top() << std::endl;s.pop();std::cout << "Top element after pop: " << s.top() << std::endl;std::cout << "Stack size: " << s.size() << std::endl;return 0;
}

常见应用

括号匹配问题

给定一个包含括号((), {}, [])的字符串,判断括号是否匹配。

算法思想

遇到左括号时入栈,遇到右括号时出栈,匹配时继续,如果匹配失败或者栈为空,则不匹配。

代码实现(c++)

#include <iostream>
#include <stack>
#include <string>bool isValid(const std::string& s) {std::stack<char> stack;for (auto c : s) {if (c == '(' || c == '{' || c == '[') {stack.push(c);} else {if (stack.empty()) return false;char top = stack.top();stack.pop();if (c == ')' && top != '(') return false;if (c == '}' && top != '{') return false;if (c == ']' && top != '[') return false;}}return stack.empty();
}int main() {std::string s = "{[()]}";if (isValid(s)) {std::cout << "Valid" << std::endl;} else {std::cout << "Invalid" << std::endl;}return 0;
}

逆波兰表达式求值

逆波兰表达式是一种后缀表达式,运算符位于操作数后面,利用栈来计算结果。

算法思想

通过扫描逆波兰表达式,将数字压入栈中,遇到运算符时从栈中弹出操作数,进行运算后再将结果压回栈中。

代码实现(c++)

#include <iostream>
#include <stack>
#include <sstream>
#include <string>
#include <cctype>int evalRPN(const std::vector<std::string>& tokens) {std::stack<int> stack;for (const auto& token : tokens) {if (isdigit(token[0]) || (token[0] == '-' && token.size() > 1 && isdigit(token[1]))) {stack.push(std::stoi(token));} else {int b = stack.top(); stack.pop();int a = stack.top(); stack.pop();if (token == "+") stack.push(a + b);else if (token == "-") stack.push(a - b);else if (token == "*") stack.push(a * b);else if (token == "/") stack.push(a / b);}}return stack.top();
}int main() {std::vector<std::string> tokens = {"2", "1", "+", "3", "*"};std::cout << "Result: " << evalRPN(tokens) << std::endl;return 0;
}

DFS(深度优先搜索)

在图或树的遍历中,DFS 使用栈来保存节点,以便后续访问。

算法思想

将起始节点入栈,访问节点并标记,然后将未访问的邻接节点入栈,直到没有未访问的节点。

代码实现(c++)

#include <iostream>
#include <vector>
#include <stack>void DFS(int start, const std::vector<std::vector<int>>& graph) {std::vector<bool> visited(graph.size(), false);std::stack<int> stack;stack.push(start);while (!stack.empty()) {int node = stack.top();stack.pop();if (!visited[node]) {std::cout << node << " ";visited[node] = true;}for (int neighbor : graph[node]) {if (!visited[neighbor]) {stack.push(neighbor);}}}
}int main() {std::vector<std::vector<int>> graph = {{1, 2},      // Node 0 connected to nodes 1 and 2{0, 3, 4},   // Node 1 connected to nodes 0, 3, 4{0, 5},      // Node 2 connected to nodes 0, 5{1},         // Node 3 connected to node 1{1},         // Node 4 connected to node 1{2}          // Node 5 connected to node 2};DFS(0, graph);  // Starting from node 0return 0;
}

求括号表达式的结果

计算一个包含括号的表达式值,可以通过使用栈来辅助计算。

算法思想

使用栈保存操作数和运算符,在遇到括号时,处理内部表达式。

代码实现(c++)

#include <iostream>
#include <stack>
#include <string>int calculate(const std::string& s) {std::stack<int> stack;int num = 0, result = 0, sign = 1;  // sign: 1 表示正,-1 表示负for (char c : s) {if (isdigit(c)) {num = num * 10 + (c - '0');} else if (c == '+') {result += sign * num;sign = 1;num = 0;} else if (c == '-') {result += sign * num;sign = -1;num = 0;} else if (c == '(') {stack.push(result);stack.push(sign);result = 0;sign = 1;} else if (c == ')') {result += sign * num;num = 0;result *= stack.top(); stack.pop();  // Apply previous signresult += stack.top(); stack.pop();  // Add previous result}}result += sign * num;return result;
}int main() {std::string expr = "1 + (2 - (3 + 4))";std::cout << "Result: " << calculate(expr) << std::endl;return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/475484.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【数据结构】用四个例子来理解动态规划算法

1. 动态规划 动态规划&#xff08;Dynamic Programming, DP&#xff09;是一种通过将复杂问题分解为更小的子问题来求解的算法设计思想&#xff0c;一般用于求解具有最优子结构和重叠子问题性质的问题。动态规划的核心在于&#xff1a;&#xff08;1&#xff09;最优子结构--问…

前端两大利器:Vue与TypeScript的渊源

Vue 在前端领域占据着重要地位&#xff0c;是最受欢迎的前端框架之一。它被广泛应用于各种类型的 Web 应用开发&#xff0c;从简单的小型项目&#xff0c;如个人博客、公司宣传网站等&#xff0c;到复杂的大型企业级应用&#xff0c;如电商平台、金融系统等。例如&#xff0c;许…

【Python】使用Windows任务计划程序定时运行Python脚本!

在搭建了一个python 文件以后&#xff0c;如果我们想每天一次或者多次运行这个文件&#xff0c;或者想要一天运行多个python 文件&#xff0c;推荐可以使用&#xff1a; Win的【任务计划程序】 创建【批处理文件&#xff08;.bat&#xff09;】运行Python脚本。 我们可以在Wind…

分布式数据库中间件可以用在哪些场景呢

在数字化转型的浪潮中&#xff0c;企业面临着海量数据的存储、管理和分析挑战。华为云分布式数据库中间件&#xff08;DDM&#xff09;作为一款高效的数据管理解决方案&#xff0c;致力于帮助企业在多个场景中实现数据的高效管理和应用&#xff0c;提升业务效率和用户体验。九河…

Photino:通过.NET Core构建跨平台桌面应用程序,.net国产系统

一、Photino.NET简介&#xff1a; 最近发现了一个不错的框架 Photino.Net 一份代码运行&#xff0c;三个平台 windows max linux &#xff0c;其中windows10,windows11,ubuntu 18.04,ubuntu 20.04 已测试均可以。mac 因为没有相关电脑没有测试。 github:https://github.com/t…

NAT网络地址转换——Easy IP

NAT网络地址转换 Tip&#xff1a; EasylP没有地址池的概念,使用接口地址作为NAT转换的公有地址。EasylP适用于不具备固定公网IP地址的场景:如通过DHCP, PPPOE拨号获取地址的私有网络出口,可以直接使用获取到的动态地址进行转换。 本次实验模拟nat协议配置 AR1配置如下&…

Redis五大基本类型——List列表命令详解(命令用法详解+思维导图详解)

目录 一、List列表类型介绍 二、常见命令 1、LPUSH 2、LPUSHX 3、RPUSH 4、RPUSHX 5、LRANGE 6、LPOP 7、RPOP 8、LREM 9、LSET 10、LINDEX 11、LINSERT 12、LLEN 13、阻塞版本命令 BLPOP BRPOP 三、命令小结 相关内容&#xff1a; Redis五大基本类型——Ha…

单细胞转录组学在植物系统和合成生物学中的应用进展-文献精读83

Advances in the Application of Single-Cell Transcriptomics in Plant Systems and Synthetic Biology 单细胞转录组学在植物系统和合成生物学中的应用进展 最佳实践&#xff1a;教程-文献精读80 摘要 植物是由多种细胞类型组成的复杂系统&#xff0c;其结构呈现出分层的组…

【设计模式】如何用C++实现适配器模式

【设计模式】如何用C实现适配器模式 一、问题背景 用到过很多次适配器模式&#xff0c;一直不理解为什么用这种模式&#xff0c;好像这个模式天生就该如此使用。 实际上&#xff0c;我们很多的理念都源于一些简朴的思想&#xff0c;这些思想不一定高深&#xff0c;但是在保证…

详解八大排序(一)------(插入排序,选择排序,冒泡排序,希尔排序)

文章目录 前言1.插入排序&#xff08;InsertSort&#xff09;1.1 核心思路1.2 实现代码 2.选择排序&#xff08;SelectSort&#xff09;2.1 核心思路2.2 实现代码 3.冒泡排序&#xff08;BubbleSort&#xff09;3.1 核心思路3.2 实现代码 4.希尔排序&#xff08;ShellSort&…

《Django 5 By Example》阅读笔记:p679-p765

《Django 5 By Example》学习第10天&#xff0c;p679-p765总结&#xff0c;总计87页。 一、技术总结 1.channel 书里通过聊天软件功能演示Django中channel以及异步编程的应用&#xff0c;本人对这块不是很熟悉&#xff0c;不做评价。 2.deployment(部署) services:db:imag…

kali搭建pikachu靶场

前言&#xff1a; 总所周知搭个网站需要有apachemysqlphp&#xff0c;Apache是一个开源的Web服务器软件&#xff0c; MySQL是一种关系型数据库管理系统&#xff08;数据库&#xff09;&#xff0c;PHP是一种在服务器上执行的脚本语言 文章内容来自&#xff1a;【黑帽编程与攻…

C++时间复杂度与空间复杂度

一、时间复杂度&#xff08;Time Complexity&#xff09; 1. 概念 时间复杂度是用来衡量算法运行时间随着输入规模增长而增长的量级。它主要关注的是算法执行基本操作的次数与输入规模之间的关系&#xff0c;而非具体的运行时间&#xff08;因为实际运行时间会受硬件、编程语…

【软考】系统架构设计师-信息安全技术基础

信息安全核心知识点 信息安全5要素&#xff1a;机密性、完整性、可用性、可控性、审查性 信息安全范围&#xff1a;设备安全、数据安全、内容安全、行为安全 网络安全 网络安全的隐患体现在&#xff1a;物理安全性、软件安全漏洞、不兼容使用安全漏洞、选择合适的安全哲理 …

SQL Server Management Studio 的JDBC驱动程序和IDEA 连接

一、数据库准备 &#xff08;一&#xff09;启用 TCP/IP 协议 操作入口 首先&#xff0c;我们要找到 SQL Server 配置管理器&#xff0c;操作路径为&#xff1a;通过 “此电脑” 右键选择 “管理”&#xff0c;在弹出的 “计算机管理” 窗口中&#xff0c;找到 “服务和应用程…

类和对象——static 成员,匿名对象(C++)

1.static成员 a&#xff09;⽤static修饰的成员变量&#xff0c;称之为静态成员变量&#xff0c;静态成员变量⼀定要在类外进行初始化。 b&#xff09;静态成员变量为所有类对象所共享&#xff0c;不属于某个具体的对象&#xff0c;不存在对象中&#xff0c;存放在静态区。 …

游戏引擎学习第17天

视频参考:https://www.bilibili.com/video/BV1LPUpYJEXE/ 回顾上一天的内容 1. 整体目标&#xff1a; 处理键盘输入&#xff1a;将键盘输入的处理逻辑从平台特定的代码中分离出来&#xff0c;放入更独立的函数中以便管理。优化消息循环&#xff1a;确保消息循环能够有效处理 …

【JavaEE初阶 — 多线程】线程池

目录 1. 线程池的原理 1.1 为什么要有线程池 1.2 线程池的构造方法 1.3 线程池的核心参数 1.4 TimeUnit 1.5 工作队列的类型 1.6 工厂设计模式 1.6.1 工厂模式概念 1.6.2 使用工厂模式的好处 1.6.3 使用工厂模式的典型案例 1.6.4 Thread…

基于Vue+SpringBoot的求职招聘平台

平台概述 本平台是一个高效、便捷的人才与职位匹配系统&#xff0c;旨在为求职者与招聘者提供一站式服务。平台内设三大核心角色&#xff1a;求职者、招聘者以及超级管理员&#xff0c;每个角色拥有独特的功能模块&#xff0c;确保用户能够轻松完成从信息获取到最终录用的整个…

黑马点评 秒杀下单出现的问题:服务器异常---java.lang.NullPointerException: null(已解决)

前言&#xff1a; 在此之前找了好多资料&#xff0c;查了很多&#xff0c;都没有找到对应解决的方法&#xff0c;虽然知道是userid为空&#xff0c;但不知道要修改哪里&#xff0c;还是自己的debug能力不足&#xff0c;以后得多加练习。。。 问题如下&#xff1a; 点击限时抢…