C++ STL泛型编程——在ACM中的运用
学习过C++的朋友们应该对STL和泛型编程这两个名词不会陌生。两者之间的关系不言而喻,泛型编程的思想促使了STL的诞生,而STL则很好地体现了泛型编程这种思想。这次想简单说一下STL在ACM中的一些应用。我们知道,在ACM竞赛中,经常需要用到数组、字符串、队列、堆栈、链表等数据结构和排序、搜索等算法,以提高程序的时间、空间运行效率。然而如果这些数据结构总是需要手工来编写,那无疑会是一件很麻烦的工作,而STL的出现很好地解决了这个问题。
我们简单来了解一下STL。STL提供了三种类型的组件:容器、迭代器和算法。容器主要有两类:顺序容器和关联容器。顺序容器(vector、list、deque和string等)是一系列元素的有序集合。关联容器(set、multiset、map和multimap)包括查找元素的键值。迭代器的作用是遍历容器。STL算法库包含四类算法:排序算法、不可变序算法、变序性算法和数值算法。下面就简单介绍一下STL里常用的容器。
1. vector向量容器
vector向量容器不但像数组一样对元素进行随机访问,还能在尾部插入元素,是一种简单、高效的容器,完全可以替代数组。由于vector具有内存自动管理的功能,对于元素的插入和删除,可动态调整所占的内存空间,因此使用时不需要考虑释放空间的问题。使用vector向量容器时,需要包含头文件“vector”。(即#include <vector>)对于vector容器的容量定义,可以事先定义一个固定大小,事后可以随时调整其大小;(例如vector<int> v(10); //定义一个用来存储10个int类型元素的向量容器)也可以事先不用定义其大小,使用push_back()方法从尾部扩张元素,也可以使用insert()在某个元素位置前插入新元素。
vector容器有两个重要的方法,begin()和end()。begin()返回的是首元素位置的迭代器;end()返回的是最后一个元素的下一个元素位置的迭代器。通常在遍历vector所有元素时会用到这两个方法。例如:
vector< int > v(3); vector< int >::iterator it; for (it=v.begin(); it!=v.end(); it++){...} |
至于vector元素的删除,调用erase()方法可以删除vector中迭代器所指的一个元素或一段区间中的所有元素,clear()方法则可以删除vector中所有元素。
通过使用size()方法可以返回向量的大小,即元素个数,调用empty()方法返回向量是否为空。
再简单看一下在vector中常用到的算法。使用reverse()反向排列算法,需要定义头文件“#include <algorithm>”,reverse()算法可将向量中某段迭代器区间元素反向排列;使用sort算法可以对向量排序,默认情况下对元素进行升序排列,也可以自己设计排序比较函数,具体使用细节就不赘述了。
2. string基本字符系列容器
C语言中对于字符串只能使用字符数组来处理,显得十分不方便。C++ STL提供了string基本字符序列容器来处理字符串,可以把string理解为字符串类,它提供了添加、删除、替换、查找和比较等丰富方法。使用string容器需要包含头文件声明“#include <string>”。
3. set集合容器
set集合容器实现了红黑树的平衡二叉检索树的数据结构,在插入元素时,它会自动调整二叉树的排列,把该元素放到适当的位置,以确保每个子树根节点的键值大于左子树所有节点的键值,而小于右子树所有节点的键值;另外,还得确保根节点左子树的高度与右子树的高度相等,因为二叉树高度最小,检索速度最快。这里要注意的是,set容器不会插入相同键值的元素。
平衡二叉检索树的检索使用中序遍历算法,检索效率高于vector、deque和list等容器。另外,采用中序遍历算法可将键值由小到大遍历出来,所以,可以理解为平衡二叉检索树在插入元素时,就会自动将元素按键值由小到大的顺序排列。由于构造set集合的主要目的就是为了快速检索,对于set容器中的键值,不可直接去修改。multiset、map和multimap的内部结构也是平衡二叉检索树。
4. multiset多重集合容器
multiset与set一样,也是使用红黑树来组织元素数据的,唯一不同的是,multiset允许重复的元素键值插入,而set则不允许。multiset也需要声明头文件包含“#include <set>”,由于它包含重复元素,所以在插入元素、删除元素、查找元素上较set有差别。
5. map映照容器
map映照容器的元素数据是由一个键值和一个映照数据组成的,键值与映照数据之间具有一一映照的关系。map映照容器的数据结构也是采用红黑树来实现的,插入元素的键值不允许重复,比较函数只对元素的键值进行比较,元素的各项数据可通过键值检索出来。由于map与set采用的都是红黑树的数据结构,所以它们的用法基本类似。使用map容器需要头文件包含语句“#include <map>”。
6. multiset多重映照容器
multiset与map基本相同,唯独不同的是,mulitiset允许插入重复键值的元素。由于允许重复键值存在,所以multiset的元素插入、删除、查找都与map不相同。
7. deque双端队列容器
deque双端队列容器与vector一样,采用线性表顺序存储结构。但与vector唯一不同的是,deque采用分块的线性存储结构来存储数据,每块的大小一般为512字节,称为一个deque块,所有的deque块使用一个Map块进行管理,每个Map数据项纪录每个deque块的首地址。这样,deque块在头部和尾部都可插入和删除元素,而不需移动其他元素。一般来说,当考虑到容器元素的内存分配策略和操作的性能时,deque相对于vector会更有优势。使用deque需要声明头文件包含“#include <deque>”。
8. list双向链表容器
list容器实现了双向链表的数据结构,数据元素是通过链表指针串连成逻辑意义上的线性表,这样,对链表的任一位置的元素进行插入、删除和查找都是极快速的。由于list对象的节点并不要求在一段连续的内存中,所以对于迭代器,只能通过“++”或“--”的操作将迭代器移动到后继/前驱节点元素处。而不能对迭代器进行+n或-n的操作,这点是与vector等不同的地方。使用list需要声明头文件包含“#include <list>”。
9. stack堆栈容器
stack堆栈是一个后进先出的线性表,插入和删除元素都只能在表的一端进行。插入元素的一端称为栈顶,另一端称为栈底。插入元素叫入栈,元素的删除称为出栈。要使用stack必须声明头文件包含语句“#include <stack>”。
10. queue队列容器
queue队列容器是一个先进先出的线性存储表,元素的插入只能在队尾,元素的删除只能在队首。使用queue需要声明头文件包含语句“#include <queue>” 。
原文作者:黑剑 出处:http://www.cnblogs.com/blacksword/
C++ STL泛型编程——在ACM中的运用的更多相关文章
- stl 在 acm中的应用总结
总结一些在acm中常用的小技巧,小函数 之前尝试着总结过很多次.都失败了,因为总是担心不全,理解的也不是很透彻.这次再来一次...其实之前保存了很多的草稿就不发布了,当然,下面说的很不全面,路过的大牛 ...
- ACM 中常用的算法有哪些? 2014-08-21 21:15 40人阅读 评论(0) 收藏
ACM 中常用的算法有哪些?作者: 张俊Michael 网络上流传的答案有很多,估计提问者也曾经去网上搜过.所以根据自己微薄的经验提点看法. 我ACM初期是训练编码能力,以水题为主(就是没有任何算法, ...
- ACM中使用 JAVA v2. 1
ACM中使用JAVA v2.1 严明超 (Blog:mingchaoyan.blogbus.com Email:mingchaoyan@gmail.com) 0.前 言 文前声明:本文只谈java用于 ...
- [ACM训练] ACM中巧用文件的输入输出来改写acm程序的输入输出 + ACM中八大输入输出格式
ACM中巧用文件的输入输出来改写acm程序的输入输出 经常有见大神们使用文件来代替ACM程序中的IO,尤其是当程序IO比较复杂时,可以使自己能够更专注于代码的测试,而不是怎样敲输入. C/C++代码中 ...
- 关于 矩阵在ACM中的应用
关于矩阵在ACM中的应用 1.矩阵运算法则 重点说说矩阵与矩阵的乘法,不说加减法. 支持: 结合律 (AB)C = A(BC) 分配律 A(B+C) = AB + AB $\left( \lambd ...
- Java在ACM中的应用
Java在ACM中的应用 —. 在java中的基本头文件(java中叫包) import java.io.*; import java.util.*; //输入Scanner import java. ...
- IO/ACM中来自浮点数的陷阱(收集向)
OI/ACM中经常要用到小数来解决问题(概率.计算几何等),但是小数在计算机中的存储方式是浮点数而不是我们在作数学运算中的数,有精度的限制. 以下以GUN C++为准,其他语言(或编译器)也差不了多少 ...
- ACM中的浮点数精度处理
在ACM中,精度问题非常常见.其中计算几何头疼的地方一般在于代码量大和精度问题,代码量问题只要平时注意积累模板一般就不成问题了.精度问题则不好说,有时候一个精度问题就可能成为一道题的瓶颈,让你debu ...
- ACM中Java的应用
先说一下Java对于ACM的一些优点吧: (1) 对于熟悉C/C++的程序员来说Java 并不难学,两周时间基本可以搞定一般的编程,再用些时间了解一下Java库就行了.Java的语法和C++非常类似, ...
随机推荐
- UITableViewCell里面separator的设置
最近cell显示的时候左边一直有15个像素的偏移,查了下面的方法 //1. 不管用 [self.tableView setSeparatorInset:UIEdgeInsetsZero]; // 2. ...
- codeblocks个性化配置
1.general setting设置默认字体大小设置控制台字体大小:"Settings -> Environment -> View -> Message logs' f ...
- JavaScript判断数据类型
JavaScript中判断数据类型的方式有三种: 1.typeof typeof 1; //"number" typeof "abc"; //" ...
- Fragment的使用(二)
动态添加Fragment 将MainActivity的布局文件中的两个Fragment的代码注释掉.在MainActivity的java文件中添加如下代码: package com.cm.myfrag ...
- 电脑重装系统后如何恢复Mysql数据库
电脑重装系统后如何恢复Mysql数据库 一.[设置mysql的path]
- 一些初级Java错误,不定期增加
1. Error: Dangling meta character '*' near index 0 对字符串使用split()方法截取 * ? + / | 等字符的时候会报以下异常 Dangling ...
- 使用恶意USB设备解锁 Windows & Mac 锁屏状态
NSA专业物理入侵设备——USB Armory,可解锁任意锁屏状态的下的Windows和Mac操作系统,含最新发布的Windows10.及较早的Mac OSX El Capitan / Maveric ...
- GSM Hacking Part① :使用SDR扫描嗅探GSM网络
0×00 写在开头 近期,发现Crazy Danish Hacker在YouTuBe发布了一个挺不错的教程视频:使用SDR嗅探监听GSM网络的通信流量(GSM Sniffing Teaser – So ...
- ubuntu卸载安装mysql
安装(转自http://www.cnblogs.com/xz1024/p/5802637.html): deb安装: 一.下载MySQL 到mysql网站下载相应的mysql安装包,我的mysql-s ...
- c++继承,多态,重载的作用
继承:用户通过继承,可以从一个类派生出多个子类,减少了重新定义类的次数,并且在不影响子类的相应功能的情况下,保护了基类中的数据安全性.用户还可以在子类中,使用与基类相同的行为实现不同的功能,因此,使用 ...