当前位置: 首页 > 编程日记 > 正文

C++/C++11中std::stack的使用

栈stack 是一个容器适配器(container adaptor)类型,被特别设计用来运行于LIFO(Last-in First-out,后进先出)场景,在该场景中,只能从容器末尾添加和删除元素,其定义在stack头文件中。stack默认基于std::deque实现,也可以在std::list或std::vector之上实现。

stack 通常被实现为容器适配器,即使用一个特定容器类的封装对象作为它的底层容器。stack 提供了一系列成员函数用于操作它的元素,只能从容器”后面”压进(Push)元素或从容器”后面”提取(Pop)元素。容器中的”后面”位置也被称为”栈顶”。用来实现栈的底层容器必须满足顺序容器的所有必要条件。同时,它还必须提供以下语义的成员函数:back()、push_back()​、pop_back()。满足上述条件的标准容器有 std::vector、std::deque 及 std::list,如果未特别指定 stack 的底层容器,标准容器 std::deque 将被使用。

Stacks are a type of container adaptor, specifically designed to operate in a LIFO context(last-in first-out), where elements are inserted and extracted only from one end of the container.

stacks are implemented as containers adaptors, which are classes that use an encapsulated object of a specific container class as its underlying container,providing a specific set of member functions to access its elements. Elements are pushed/popped from the "back" of the specific container, which is known as the top of the stack.

一个容器就是一些特定类型对象的集合。顺序容器(sequential container)为程序员提供了控制元素存储和访问顺序的能力。这种顺序不依赖于元素的值,而是与元素加入容器时的位置相对应。

标准库中的顺序容器包括:

(1)、vector:可变大小数组。支持快速随机访问。在尾部之外的位置插入或删除元素可能很慢。

(2)、deque:双端队列。支持快速随机访问。在头尾位置插入/删除速度很快。

(3)、list:双向链表。只支持双向顺序访问。在list中任何位置进行插入/删除操作速度都很快。

(4)、forward_list:单向链表。只支持单向顺序访问。在链表任何位置进行插入/删除操作速度都很快。

(5)、array:固定大小数组。支持快速随机访问。不能添加或删除元素。

(6)、string:与vector相似的容器,但专门用于保存字符。随机访问快。在尾部插入/删除速度快。

除了固定大小的array外,其它容器都提供高效、灵活的内存管理。我们可以添加和删除元素,扩张和收缩容器的大小。容器保存元素的策略对容器操作的效率有着固定的,有时是重大的影响。在某些情况下,存储策略还会影响特定容器是否支持特定操作。

例如,string和vector将元素保存在连续的内存空间中。由于元素是连续存储的,由元素的下标来计算其地址是非常快速的。但是,在这两种容器的中间位置添加或删除元素就会非常耗时:在一次插入或删除操作后,需要移动插入/删除位置之后的所有元素,来保持连续存储。而且,添加一个元素有时可能还需要分配额外的存储空间。在这种情况下,每个元素都必须移动到新的存储空间中。

list和forward_list两个容器的设计目的是令容器任何位置的添加和删除操作都很快速。作为代价,这两个容器不支持元素的随机访问:为了访问一个元素,我们只能遍历整个容器。而且,与vector、deque和array相比,这两个容器的额外内存开销也很大。

deque是一个更为复杂的数据结构。与string和vector类似,deque支持快速的随机访问。与string和vector一样,在deque的中间位置添加或删除元素的代价(可能)很高。但是,在deque的两端添加或删除元素都是很快的,与list或forward_list添加删除元素的速度相当。

forward_list和array是新C++标准增加的类型。与内置数组相比,array是一个种更安全、更容易使用的数组类型。与内置数组类似,array对象的大小是固定的。因此,array不支持添加和删除元素以及改变容器大小的操作。forward_list的设计目标是达到与最好的手写的单向链表数据结构相当的性能。因此,forward_list没有size操作,因为保存或计算其大小就会比手写链表多出额外的开销。对其他容器而言,size保证是一个快速的常量时间的操作。

通常,使用vector是最好的选择,除法你有很好的理由选择其他容器。

以下是一些选择容器的基本原则:

(1)、除法你有很好的理由选择其他容器,否则应该使用vector;

(2)、如果你的程序有很多小的元素,且空间的额外开销很重要,则不要使用list或forward_list;

(3)、如果程序要求随机访问元素,应使用vector或deque;

(4)、如果程序要求在容器的中间插入或删除元素,应使用list或forward_list;

(5)、如果程序需要在头尾位置插入或删除元素,但不会在中间位置进行插入或删除操作,则使用deque;

(6)、如果程序只有在读取输入时才需要在容器中间位置插入元素,随后需要随机访问元素,则:首先,确定是否真的需要在容器中间位置添加元素。当处理输入数据时, 通常可以很容器地向vector追加数据,然后再调用标准库的sort函数来重排容器中的元素,从而避免在中间位置添加元素。如果必须在中间位置插入元素,考虑在输入阶段使用list,一旦输入完成,将list中的内容拷贝到一个vector中。

如果你不确定应该使用哪种容器,那么可以在程序中只使用vector和list公共的操作:使用迭代器,不使用下标操作,避免随机访问。这样,在必要时选择使用vector或list都很方便。

一般来说,每个容器都定义在一个头文件中,文件名与类型名相同。即,deque定义在头文件deque中,list定义在头文件list中,以此类推。容器均定义为模板类。

顺序容器几乎可以保存任意类型的元素。特别是,我们可以定义一个容器,其元素的类型是另一个容器。这种容器的定义与任何其他容器类型完全一样:在尖括号中指定元素类型(此种情况下,是另一种容器类型)。

除了顺序容器外,标准库还定义了三个顺序容器适配器:stack、queue和priority_queue。适配器(adaptor)是标准库中的一个通用概念。容器、迭代器和函数都有适配器。本质上,一个适配器是一种机制,能使某种事物的行为看起来像另外一种事物一样。一个容器适配器接受一种已有的容器类型,使其行为看起来像一种不同的类型。

下面是从其他文章中copy的测试代码,详细内容介绍可以参考对应的reference:

#include "stack.hpp"
#include <iostream>
#include <stack>
#include <vector>
#include <deque>
#include <list>
#include <string>// https://msdn.microsoft.com/en-us/library/56fa1zk5.aspx
int test_stack_2()
{using namespace std;// Declares stack with default deque base container  stack <char> dsc1;//Explicitly declares a stack with deque base container  stack <char, deque<char> > dsc2;// Declares a stack with vector base containers  stack <int, vector<int> > vsi1;// Declares a stack with list base container  stack <int, list<int> > lsi;// The second member function copies elements from a container  vector<int> v1;v1.push_back(1);stack <int, vector<int> > vsi2(v1);cout << "The element at the top of stack vsi2 is "<< vsi2.top() << "." << endl;return 0;
}///
// reference: http://www.cplusplus.com/reference/stack/stack/
int test_stack_1()
{
{ // stack::stack: Constructs a stack container adaptor objectstd::deque<int> mydeque(3, 100);          // deque with 3 elementsstd::vector<int> myvector(2, 200);        // vector with 2 elementsstd::stack<int> first;                    // empty stackstd::stack<int> second(mydeque);         // stack initialized to copy of dequestd::stack<int, std::vector<int> > third;  // empty stack using vectorstd::stack<int, std::vector<int> > fourth(myvector);std::cout << "size of first: " << first.size() << '\n';std::cout << "size of second: " << second.size() << '\n';std::cout << "size of third: " << third.size() << '\n';std::cout << "size of fourth: " << fourth.size() << '\n';
}{ // stack::emplace: c++11, Adds a new element at the top of the stack, above its current top element.// This new element is constructed in place passing args as the arguments for its constructorstd::stack<std::string> mystack;mystack.emplace("First sentence");mystack.emplace("Second sentence");std::cout << "mystack contains:\n";while (!mystack.empty()) {std::cout << mystack.top() << '\n';mystack.pop();}
}{ // stack::empty: Returns whether the stack is empty: i.e. whether its size is zero// stack::pop: Removes the element on top of the stack, effectively reducing its size by one// stack::push: Inserts a new element at the top of the stack, above its current top element.// The content of this new element is initialized to a copy of val.std::stack<int> mystack;int sum(0);for (int i = 1; i <= 10; i++) mystack.push(i);while (!mystack.empty()) {sum += mystack.top();mystack.pop();}std::cout << "total: " << sum << '\n';
}{ // stack::size: Returns the number of elements in the stack.std::stack<int> myints;std::cout << "0. size: " << myints.size() << '\n';for (int i = 0; i < 5; i++) myints.push(i);std::cout << "1. size: " << myints.size() << '\n';myints.pop();std::cout << "2. size: " << myints.size() << '\n';
}{ // stack::swap: Exchanges the contents of the container adaptor (*this) by those of x.std::stack<int> foo, bar;foo.push(10); foo.push(20); foo.push(30);bar.push(111); bar.push(222);foo.swap(bar);// std::swap(foo, bar);std::cout << "size of foo: " << foo.size() << '\n';std::cout << "size of bar: " << bar.size() << '\n';
}{ // stack::top: Returns a reference to the top element in the stack. std::stack<int> mystack;mystack.push(10);mystack.push(20);mystack.top() -= 5;std::cout << "mystack.top() is now " << mystack.top() << '\n';
}return 0;
}

GitHub: https://github.com/fengbingchun/Messy_Test

相关文章:

团队前四次作业——个人总结

团队前四次作业——个人总结 描述 团队名称待就业六人组相关团队第四次作业答辩——反思与总结做了哪些事&#xff1f;工作量、完成度 作业负责工作量完成度团队队员展示创意合照后期1h95%项目选题报告编写创新和收益部分2h85%项目原型设计原型设计6h95%需求规格说明书功能需求…

吴甘沙:天外飞“厕”、红绿灯消失,未来无人驾驶将被重新定义 | AI ProCon 2019

2019 年9 月 5 日至 7 日&#xff0c;由新一代人工智能产业技术创新战略联盟&#xff08;AITISA&#xff09;指导&#xff0c;鹏城实验室、北京智源人工智能研究院支持&#xff0c;专业中文 IT 技术社区 CSDN 主办的 2019 中国 AI 开发者大会&#xff08;AI ProCon 2019&#x…

MySQL基础day03_数据的导入、导出-MySQL 5.6

MySQL基础day03_数据的导入、导出-MySQL 5.6注&#xff1a;把数据按照一定格式存放到文件里才能进行数据的导入。1&#xff0c;数据导入的条件把文件里的内容保存到数据的表里&#xff1b;把数据按照一定格式存放文件里&#xff1b;注&#xff1a;默认情况下&#xff0c;只有管…

“含光”剑出,谁与争锋?阿里重磅发布首颗AI芯片含光800

作者 | 夕颜、胡巍巍 编辑 | 唐小引 出品 | AI 科技大本营&#xff08;ID:rgznai100&#xff09; 9 月末的杭州气温适宜&#xff0c;宜出游&#xff0c;宜在湖边餐厅浅酌一杯清茶消闲。但在钱塘江水支流河畔的云栖小镇&#xff0c;却完全一副与闲适氛围不相称的热闹景象。 …

c++面试题中经常被面试官面试的小问题总结(一)(本篇偏向基础知识)

原文作者&#xff1a;aircraft 原文链接&#xff1a;https://www.cnblogs.com/DOMLX/p/10711810.html 1.类中的函数定义后加了一个const代表什么&#xff1f; 代表它将具备以下三个性质&#xff1a;1.const对象只能调用const成员函数。2.const对象的值不能被修改&#xff0c;在…

矩阵特征分解介绍及雅克比(Jacobi)方法实现特征值和特征向量的求解(C++/OpenCV/Eigen)

对角矩阵(diagonal matrix)&#xff1a;只在主对角线上含有非零元素&#xff0c;其它位置都是零&#xff0c;对角线上的元素可以为0或其它值。形式上&#xff0c;矩阵D是对角矩阵&#xff0c;当且仅当对于所有的i≠j, Di,j 0. 单位矩阵就是对角矩阵&#xff0c;对角元素全部是1…

Entity Framework CodeFirst数据迁移

原文:Entity Framework CodeFirst数据迁移前言 紧接着前面一篇博文Entity Framework CodeFirst尝试。 我们知道无论是“Database First”还是“Model First”当模型发生改变了都可以通过Visual Studio设计视图进行更新&#xff0c;那么对于Code First如何更新已有的模型呢&…

限时早鸟票 | 2019 中国大数据技术大会(BDTC)超豪华盛宴抢先看!

2019 年12月5-7 日&#xff0c;由中国计算机学会主办&#xff0c;CCF 大数据专家委员会承办&#xff0c;CSDN、中科天玑数据科技股份有限公司协办的 2019 中国大数据技术大会&#xff0c;将于北京长城饭店隆重举行。届时&#xff0c;超过百位技术专家及行业领袖将齐聚于此&…

Google AI 系统 DeepMind无法通过 高中数学

Google 旗下 DeepMind 团队让 AI 系统接受一项高中程度的数学测试&#xff0c;结果在 40 道题目中只答对了 14 题&#xff0c;甚至连「1111111」也算错了。说来难以置信&#xff0c;Google AI 系统能打败人类世界棋王&#xff0c;却无法通过高中程度的数学考试。上周&#xff0…

C++11中std::tuple的使用

std::tuple是类似pair的模板。每个pair的成员类型都不相同&#xff0c;但每个pair都恰好有两个成员。不同std::tuple类型的成员类型也不相同&#xff0c;但一个std::tuple可以有任意数量的成员。每个确定的std::tuple类型的成员数目是固定的&#xff0c;但一个std::tuple类型的…

PHP Countable接口

实现该接口可以使用count()方法来获取集合的总数转载于:https://www.cnblogs.com/xiaodo0/p/3611307.html

矩阵奇异值分解简介及C++/OpenCV/Eigen的三种实现

奇异值分解(singular value decomposition, SVD)&#xff1a;将矩阵分解为奇异向量(singular vector)和奇异值(singular value)。通过奇异值分解&#xff0c;我们会得到一些与特征分解相同类型的信息。然而&#xff0c;奇异值分解有更广泛的应用。每个实数矩阵都有一个奇异值分…

经典!工业界深度推荐系统与CTR预估必读的论文汇总

&#xff08;图片付费下载自视觉中国&#xff09;来源 | 深度传送门&#xff08;ID: gh_5faae7b50fc5&#xff09;导读&#xff1a;本文是“深度推荐系统”专栏的第十一篇文章&#xff0c;这个系列将介绍在深度学习的强力驱动下&#xff0c;给推荐系统工业界所带来的最前沿的变…

docker上传自己的镜像

https://blog.csdn.net/boonya/article/details/74906927 需要注意的就是命名规范 docker push 注册用户名/镜像名 tag命令修改为规范的镜像&#xff1a; docker tag boonya/tomcat-allow-remote boonyadocker/tomcat-allow-remote转载于:https://www.cnblogs.com/MC-Curry/p/1…

多个class相同的input标签 获取当前值!方法!

2019独角兽企业重金招聘Python工程师标准>>> var a $(this).prev( ".你的class" ).val(); 转载于:https://my.oschina.net/u/1169079/blog/210082

C++11中std::forward_list单向链表的使用

std::forward_list是在C11中引入的单向链表或叫正向列表。forward_list具有插入、删除表项速度快、消耗内存空间少的特点&#xff0c;但只能向前遍历。与其它序列容器(array、vector、deque)相比&#xff0c;forward_list在容器内任意位置的成员的插入、提取(extracting)、移动…

即学即用的30段Python实用代码

&#xff08;图片付费下载自视觉中国&#xff09;原标题 | 30 Helpful Python Snippets That You Can Learn in 30 Seconds or Less作 者 | Fatos Morina翻 译 | Pita & AI开发者Python是目前最流行的语言之一&#xff0c;它在数据科学、机器学习、web开发、脚本编写、自…

如何配置IntelliJ IDEA发布JavaEE项目?

一、以war的形式运行项目 步骤1 新建或者导入项目后&#xff0c;选择File菜单-》Project Structure...&#xff0c;如下图&#xff1a; 步骤2 配置项目类型&#xff0c;名字可以自定义&#xff1a; 说明&#xff1a;这里的Artifact如果没有配置好的话&#xff0c;配置Tomcat时没…

网络分布式软件bonic清除

近期&#xff0c;有一款网格计算软件&#xff0c;在很多服务器上进行了部署&#xff0c;利用cpu进行运算。虽然未构成安全隐患&#xff0c;但是比较消耗资源&#xff0c;影响设备正常运行。今天对设备彻底检查&#xff0c;发现了一个分布式计算软件boinc&#xff0c;他是利用网…

C++/C++11中std::list双向链表的使用

std::list是双向链表&#xff0c;是一个允许在序列中任何一处位置以常量耗时插入或删除元素且可以双向迭代的顺序容器。std::list中的每个元素保存了定位前一个元素及后一个元素的信息&#xff0c;允许在任何一处位置以常量耗时进行插入或删除操作&#xff0c;但不能进行直接随…

React组件设计之边界划分原则

简述 结合SOLID中的单一职责原则来进行组件的设计 Do one thing and do it well javaScript作为一个弱类型并在函数式和面对对象的领域里疯狂试探语言。SOLID原则可能与其他语言例如&#xff08;java&#xff09;的表现可能是不同的。不过作为软件开发领域通用的原则&#xff0…

阿里AI labs发布两大天猫精灵新品,将与平头哥共同定制智能语音芯片

作者 | 夕颜出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09;2019 年&#xff0c;去年刮起的一阵智能音箱热浪似乎稍微冷却下来&#xff0c;新产品不再像雨后春笋一样层出不穷&#xff0c;挺过市场洗礼的产品更是凤毛麟角&#xff0c;这些产品的性能、技术支持和体验基…

js 中文匹配正则

为什么80%的码农都做不了架构师&#xff1f;>>> /^[\u4e00-\u9fa5]{2,4}$/gi.test() 匹配中文正则 转载于:https://my.oschina.net/fedde/blog/211852

Caffe中对cifar10执行train操作

参考Caffe source中examples/cifar10目录下内容。cifar10是一个用于普通物体识别的数据集&#xff0c;cifar10被分为10类,分别为airplane、automobile、bird、cat、deer、dog、frog、horse、ship、truck&#xff0c;关于cifar10的详细介绍可以参考&#xff1a; http://blog.csd…

解决掉这些痛点和难点,让知识图谱不再是“噱头”

&#xff08;图片付费下载自视觉中国&#xff09;作者| 夕颜出品| AI科技大本营&#xff08;ID:rgznai100&#xff09;2012 年&#xff0c;谷歌正式提出知识图谱的概念&#xff0c;当时&#xff0c;研究人员的主要目的是用来优化搜索引擎技术。今年初&#xff0c;谷歌前员工&am…

mongodb使用常用语法,持续更新

设置快捷命令D:\mongodb4.0.8\bin>mongod --config "D:\mongodb4.0.8\mongo.conf" --auth --install --serviceName "MongoDB"mongodb配置文件#数据库路径dbpathD:\mongodb4.0.8\data\db#日志输出文件路径logpathD:\mongodb4.0.8\data\log\MongoDB.log#…

Android之NDK开发的简单实例

NDK全称为Native Development Kit&#xff0c;是本地开发工具集。在Android开发中&#xff0c;有时为了能更好的重用以前的C/C的代码&#xff0c;需要将这些代码编译成相应的so&#xff0c;然后通地JNI以供上层JAVA调用。当然&#xff0c;也有的是为了更高的保护性和安全性。下…

阿里披露AI完整布局,飞天AI平台首次亮相

作者 | 夕颜编辑 | 唐小引出品 | AI 科技大本营&#xff08;ID:rgznai100&#xff09;9 月 26 日上午&#xff0c;在云栖大会阿里云飞天智能主论坛上&#xff0c;年轻的阿里巴巴副总裁、阿里云智能计算平台事业部总经理、高级研究员贾扬清与其在 Facebook 的老同事—— Faceboo…

使用Caffe基于cifar10进行物体识别

在http://blog.csdn.net/fengbingchun/article/details/72953284中对cifar10进行train&#xff0c;这里通过train得到的model&#xff0c;对图像进行识别。cifar10数据集共包括10类&#xff0c;按照0到9的顺序依次为airplane(飞机)、automobile(轿车)、bird(鸟)、cat(猫)、deer…

SoJpt Boot 2.3-3.8 发布,Spring Boot 使用 Jfinal 特性极速开发

SoJpt Boot 2.3-3.8 发布了。SoJpt Boot 基于 JFinal 与 Spring Boot制作, 实现了 Spring Boot 与 Jfinal 的混合双打,使 Spring Boot 下的开发者能够体验 Jfinal 的极速开发特性。新版更新内容如下&#xff1a; SoJpt-Boot-2.3-3.8 changelog 1、加入事务注解,Tx(value"c…