突破编程_C++_面试(STL 编程 stack)

1 请简述 std::stack 在 C++ STL 中的基本功能和使用场景

std::stack在C++ STL(标准模板库)中是一个容器适配器,专门用于实现后进先出(LIFO,Last-In-First-Out)的数据结构。其基本功能和使用场景如下:

基本功能:

  • push(element):向栈顶添加元素。
  • pop():移除栈顶元素。如果栈为空,则此操作可能会导致未定义行为。
  • top():返回栈顶元素的引用,但不移除它。如果栈为空,则此操作可能会导致未定义行为。
  • empty():检查栈是否为空。如果栈为空,则返回true;否则返回false。
  • size():返回栈中元素的数量。

此外,std::stack还提供了其他一些成员函数,例如emplace()(C++11 起可用,用于在栈顶构造并添加元素)和 swap()(用于交换两个栈的内容)。

使用场景:

std::stack适用于那些需要后进先出访问顺序的场景。这种数据结构在许多算法和实际问题中都非常有用。以下是一些具体的使用场景示例:

  • 函数调用栈:在计算机科学中,函数调用栈就是一个典型的后进先出结构。每次函数调用时,相关信息(如局部变量、返回地址等)被推入栈中;函数返回时,这些信息从栈中弹出。
  • 撤销操作:在编辑文本或图形时,撤销功能通常使用栈来实现。每次执行一个操作(如键入一个字符或移动一个对象),该操作都被推入撤销栈中。当用户选择撤销时,栈顶的操作被弹出并应用其逆操作。
  • 括号匹配:在解析编程语言的源代码时,通常需要检查括号是否正确匹配。可以使用栈来跟踪尚未匹配的括号,每次遇到一个开括号就将其推入栈中,遇到一个闭括号则从栈顶弹出一个元素并检查是否匹配。
  • 深度优先搜索(DFS):在图形算法中,DFS经常使用栈来保存待访问的节点。每次访问一个节点时,将其推入栈中;当当前节点没有未访问的邻居时,从栈中弹出一个节点并继续访问其邻居。

这些只是 std::stack 的一些常见使用场景,实际上它可以在任何需要后进先出访问顺序的场合中发挥作用。

2 std::stack 和 std::vector 在功能上有哪些异同?

std::stack和std::vector在C++标准模板库(STL)中都是常用的数据结构,但它们在功能和使用上存在明显的异同。

功能相同点:

  • 存储元素:两者都用于在内存中存储一系列元素。
  • 动态大小:std::vector 和 std::stack 都可以动态地调整其大小以适应更多或更少的元素。

功能不同点:

(1)访问方式:

  • std::vector提供随机访问功能,即可以通过索引直接访问其任意位置的元素。这使得std::vector非常适合需要频繁访问和修改元素的应用场景。
  • std::stack则只允许在栈顶进行元素的插入(push)和删除(pop)操作,且只能访问栈顶元素(通过top()方法)。这种限制使得std::stack只能按照后进先出(LIFO)的顺序处理元素。

(2)用途和设计目标:

  • std::vector 是一个通用且灵活的容器,可以用于各种需要动态数组的场景。它可以用来存储任意类型的对象,并且支持高效的插入、删除、访问和遍历操作。
  • std::stack 则是一个专为栈数据结构设计的容器适配器。它主要用于那些需要后进先出顺序处理元素的场景,如函数调用堆栈模拟、表达式求值的计算过程等。
    底层实现:
  • std::vector 通常使用连续的内存空间来存储元素,这使得它可以高效地进行元素的访问和移动。
  • std::stack 的底层实现则依赖于其他容器,如 std::deque 或 std::vector。默认情况下,std::stack 使用 std::deque 作为底层容器,但也可以选择其他容器来优化特定场景下的性能。

总结来说,std::stack 和 std::vector 在功能上各有侧重。std::vector 提供了灵活的随机访问和动态数组功能,而 std::stack 则专注于实现后进先出的栈数据结构。在选择使用哪个数据结构时,应根据具体的应用场景和需求来决定。

3 如何使用 std::stack 实现一个先进先出(FIFO)的数据结构?

以下是一个使用两个 std::stack 尝试模拟 FIFO 的例子:

#include <iostream>  
#include <stack>  class MyFIFO {
private:std::stack<int> inputStack;std::stack<int> outputStack;public:void push(int value) {inputStack.push(value);}int pop() {if (outputStack.empty()) {while (!inputStack.empty()) {outputStack.push(inputStack.top());inputStack.pop();}}if (outputStack.empty()) {throw std::out_of_range("FIFO is empty");}int value = outputStack.top();outputStack.pop();return value;}bool empty() const {return inputStack.empty() && outputStack.empty();}
};int main() 
{MyFIFO fifo;fifo.push(1);fifo.push(2);fifo.push(3);std::cout << fifo.pop() << std::endl;  // 输出 1  std::cout << fifo.pop() << std::endl;  // 输出 2  return 0;
}

这个 MyFIFO 类使用两个栈:inputStack 用于接收新的元素,而 outputStack 用于在调用 pop() 时提供元素。当 outputStack 为空时,pop() 会将 inputStack 中的所有元素弹出并压入 outputStack,从而反转元素的顺序。这样,最后一个进入 inputStack 的元素会第一个从 outputStack 中弹出,实现了一种类似 FIFO 的行为。但请注意,这种方法在 pop() 操作上的时间复杂度是 O(n),其中 n 是栈中的元素数量,因此效率非常低。

4 如果在 std::stack 为空的情况下调用 pop 或 top,会发生什么?

在 std::stack 为空的情况下调用 pop 或 top 会导致未定义行为(Undefined Behavior)。这意味着程序可能会崩溃、产生错误的结果或表现出其他不可预测的行为。

具体来说:

  • pop() 函数用于移除栈顶元素。如果栈是空的,调用 pop() 将会导致程序错误,因为没有元素可以被移除。
  • top() 函数用于返回栈顶元素的引用。如果栈是空的,调用 top() 也会引发未定义行为,因为没有元素可供引用。

为了避免这种情况,应该在调用 pop 或 top 之前检查栈是否为空,这可以通过调用 empty() 函数来实现。例如:

std::stack<int> myStack;  // ... 在某处可能向栈中添加元素 ...  if (!myStack.empty()) {  int topElement = myStack.top(); // 安全地获取栈顶元素  myStack.pop(); // 安全地移除栈顶元素  
} else {  // 处理栈为空的情况,例如抛出异常或返回错误代码  throw std::out_of_range("Stack is empty, cannot pop or top.");  
}

在实践中,为了避免未定义行为,应该始终确保在调用 pop 或 top 之前栈不为空。这是一种良好的编程习惯,可以帮助编写更加健壮和可靠的代码。

5 能否通过迭代的方式遍历 std::stack 中的所有元素?为什么?

不能通过迭代的方式直接遍历 std::stack 中的所有元素。这是因为 std::stack 是一个容器适配器,其设计初衷是提供后进先出(LIFO)的数据结构,而不是像 std::vector 或 std::deque 那样支持随机访问或迭代。

std::stack 的接口只提供了有限的几个操作,如 push、pop、top、empty 和 size,并没有提供迭代器(iterator)或类似机制来遍历栈中的元素。这是为了保持栈的简单性和一致性,并强调其后进先出的特性。

如果需要遍历栈中的元素,一种可能的方法是先将栈中的元素逐个弹出并存储到一个其他支持迭代的容器中(如 std::vector),然后再遍历这个容器。但请注意,这样做会改变栈的状态(即清空栈),因此如果之后还需要使用原始的栈,这种方法就不适用了。

下面是一个示例代码,展示了如何将 std::stack 中的元素转移到一个 std::vector 中,并遍历这个 vector:

#include <iostream>  
#include <stack>  
#include <vector>  int main() 
{std::stack<int> myStack;// 假设向栈中添加了一些元素  myStack.push(1);myStack.push(2);myStack.push(3);std::vector<int> myVector;while (!myStack.empty()) {myVector.push_back(myStack.top());myStack.pop();}// 现在可以遍历 vector 了  for (const auto& element : myVector) {std::cout << element << " ";}std::cout << std::endl;return 0;
}

上面代码的输出为:

3 2 1

这个输出展示了栈中元素的原始顺序(从栈底到栈顶),但由于栈是后进先出的数据结构,因此元素是以相反的顺序弹出的。

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

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

相关文章

【WPF应用9】 基本控件-Grid的对其和属性详细说明及示例

在WPF&#xff08;Windows Presentation Foundation&#xff09;中&#xff0c;Grid是一种强大的布局控件&#xff0c;它可以用来对齐和排列容器中的子元素。Grid控件允许您以行列的形式组织UI元素&#xff0c;并且可以指定行列的数量、大小和布局方式。在本文中&#xff0c;我…

C#,图论与图算法,有向图(Direct Graph)广度优先遍历(BFS,Breadth First Search)算法与源程序

1 图的广度优先遍历 图的广度优先遍历(或搜索)类似于树的广度优先遍历(参见本文的方法2)。这里唯一需要注意的是,与树不同,图可能包含循环,因此我们可能再次来到同一个节点。为了避免多次处理节点,我们使用布尔访问数组。为简单起见,假设所有顶点都可以从起始顶点到达…

ideaSSM 学员信息管理系统bootstrap开发mysql数据库web结构java编程计算机网页源码maven项目

一、源码特点 idea 开发 SSM 学员信息管理系统是一套完善的信息管理系统&#xff0c;结合SSM框架和bootstrap完成本系统&#xff0c;对理解JSP java编程开发语言有帮助系统采用SSM框架&#xff08;MVC模式开发&#xff09;&#xff0c;系统具有完整的源代码和数据库&#xff…

C语言基础知识复习(考研)

&#xff08;1&#xff09;C语言文件操作 1 什么是文件 文件有不同的类型&#xff0c;在程序设计中&#xff0c;主要用到两种文件&#xff1a; (1)程序文件。包括源程序文件(后缀为.c)、目标文件(后缀为.obj)、可执行这种文件的内容是程序代码。 (2)数据文件。文件的内容不是…

软件测试相关内容第五弹 -- 自动化测试Selenium

写在前&#xff1a;hello这里是西西~ 这边博客主要学习关于自动化测试的相关内容&#xff0c;首先了解自动化测试的相关理论知识&#xff0c;其次学习web应用中基于UI的自动化测试框架 - selemium[需要重点掌握selenium工作原理]&#xff0c;实操selenium,最后学习Junit相关知识…

当我想用ChatGPT-Next-Web来套壳Azure OpenAI Service时

使用Cloudflare worker来代理Azure OpenAI API&#xff0c; 并将其转换为兼容OpenAI的API 一直没能搞定OpenAI的订阅&#xff0c; 就因为没有搞定国外的信用卡&#xff0c; 所以就一直使用GPT-3.5来处理日常的文字生成工作&#xff0c; 例如写文档&#xff0c; 生成一些简单的脚…

AI助力生产制造质检,基于轻量级YOLOv8n模型开发构建工业生产制造场景下的瓷砖瑕疵检测识别分析系统

瓷砖生产环节一般经过原材料混合研磨、脱水、压胚、喷墨印花、淋釉、烧制、抛光&#xff0c;最后进行质量检测和包装。得益于产业自动化的发展&#xff0c;目前生产环节已基本实现无人化。而质量检测环节仍大量依赖人工完成。一般来说&#xff0c;一条产线需要配数名质检工&…

论文阅读-MIPD:一种用于分布式深度神经网络训练的自适应梯度稀疏化框架

摘要—基于参数服务器架构的异步训练广泛应用于大规模数据集和深度神经网络模型的扩展训练。在大规模分布式深度学习系统中&#xff0c;通信一直被认为是主要瓶颈。最近的研究尝试通过梯度稀疏化和量化方法来减少通信流量。我们发现前期研究存在三个限制。首先&#xff0c;他们…

秋招企业面经

元戎启行 牛客 岁月如歌&#xff08;关注&#xff09; 算法&#xff1a;回文子串&#xff0c;二叉树寻找最小路径&#xff08;回溯比较简单&#xff09;。跳楼梯 八股&#xff1a; delete会把内存还给操作系统吗&#xff1f; 进程调用delete或者free释放资源后&#xff0c…

作为前端,如何利用机器学习

当涉及到前端开发与机器学习&#xff08;Machine Learning&#xff09;的结合时&#xff0c;我们进入了一个充满创新和前沿技术的领域。机器学习作为人工智能的一个重要分支&#xff0c;已经在各个领域展示了惊人的应用潜力&#xff0c;而将其融入前端开发则为我们带来了无限可…

YOLOv5-Y5周:yolo.py文件解读

本文为&#x1f517;365天深度学习训练营 中的学习记录博客 原作者&#xff1a;K同学啊|接辅导、项目定制 我的环境&#xff1a; 1.语言&#xff1a;python3.7 2.编译器&#xff1a;pycharm 3.深度学习框架Tensorflow/Pytorch 1.8.0cu111 一、代码解读 import argparse i…

python实现生成多种文件格式:excel、csv、pdf

python实现生成多种文件格式:excel、csv、pdf import data_util, time_util import pandas as pd import matplotlib.pyplot as plt from matplotlib.backends.backend_pdf import PdfPagesif __name__ __main__:data data_util.get_superset_data()df if (len(data) > …

【洛谷 P8715】[蓝桥杯 2020 省 AB2] 子串分值 题解(组合数学+乘法原理)

[蓝桥杯 2020 省 AB2] 子串分值 题目描述 对于一个字符串 S S S, 我们定义 S S S 的分值 f ( S ) f(S) f(S) 为 S S S 中恰好出现一次的字符个数。例如 f ( ′ ′ a b a ′ ′ ) 1 f\left({ }^{\prime \prime} \mathrm{aba}{ }^{\prime \prime}\right)1 f(′′aba′′)…

编写人脸检测程序

新建一个py文件&#xff0c;命名为facedetectionwithdlib.py。添加如下代码&#xff1a; 【代码 facedetectionwithdlib.py】 # -*- coding: utf-8 -*-使用dlib实现人脸检测 import face_recognition import cv2 import time# 超参数 detection_method hog # 参数值为hog/cn…

python之内存管理

前言 python中&#xff0c;万物皆对象。 因此&#xff0c;内存的管理&#xff0c;便是管理对象从创建到销毁的过程。有效地管理内存&#xff0c;既可以减少内存碎片&#xff0c;又可以避免内存泄漏等现象&#xff08;大概讲讲&#xff09;。 内存的分配 Python内部对于内存…

ChatGPT写作宝典:解锁论文创作新技能

ChatGPT无限次数:点击直达 ChatGPT写作宝典&#xff1a;解锁论文创作新技能 在当今信息爆炸的时代&#xff0c;写作已经成为人们必备的基本技能之一。无论是撰写论文、博客还是其他形式的文字内容&#xff0c;写作都扮演着重要的角色。在这样的背景下&#xff0c;ChatGPT为我们…

Vscode与Cmake搭配配置opencv使用

vscode与Cmake基本使用 下载插件 CtrlShiftp打开VSCode的指令面板&#xff0c;然后输入cmake:q&#xff0c;VSCode会根据输入自动提示&#xff0c;然后选择CMake: Quick Start选择编译器根据提示输入项目名称选择可执行文件编译项目 方式一&#xff1a;执行命令cd build cmake…

一键将自己网增加一个抖音小程序-源代码

把自己的网址链接&#xff0c;也就是你想要的一个页面转变为抖音小程序&#xff0c;让你轻松拥有一个自己的抖音小程序。 几分钟搞定。 跟着视频来操作就可以了&#xff0c;很简单。视频一定要完整看完啊&#xff0c;对于小白。 如果你的网址可能有不好过审核的页面&#xff0c…

基于python+vue的stone音乐播放器的设计与实现flask-django-php-nodejs

随着我国经济的高速发展与人们生活水平的日益提高&#xff0c;人们对生活质量的追求也多种多样。尤其在人们生活节奏不断加快的当下&#xff0c;人们更趋向于足不出户解决生活上的问题&#xff0c;stone音乐播放器展现了其蓬勃生命力和广阔的前景。与此同时&#xff0c;为解决用…

Go使用Terraform 库

可以使用Terraform的Go库来在Go代码中运行Terraform。用户需要使用go get命令来获取Terraform的Go库。在Go代码中需要导入terraform包。下面是一个简单的示例代码&#xff0c;它使用Terraform的Go库来创建和销毁一个AWS EC2实例&#xff1a; package mainimport ("contex…