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++非常类似, ...
随机推荐
- 【jQuery】百分比自适应屏幕轮播图特效
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 配置DelegatingFilterProxy使用Spring管理filter chain
项目环境:JDK7 + Maven3.04 0. 项目使用springmvc作为controller层 1. 引入spring-security <dependency> <grou ...
- 3D图形图像处理软件HOOPS介绍及下载
HOOPS 3D Application Framework(以下简称HOOPS)是建立在OpenGL.Direct3D等图形编程接口之上的更高级别的应用程序框架.不仅为您提供强大的图形功能,还内嵌了 ...
- 使linux服务器默认使用中文字符集zh_CN.UTF-8
一.问题描述和相关概念 linux服务器的字符集设置可能影响到网站页面出现 “???” 等问号乱码,还有可能导致文件中的汉字部分出现乱码. locales设置:语言设置选项 linux真的是一个非 ...
- python获取字母在字母表对应位置的几种方法及性能对比较
python获取字母在字母表对应位置的几种方法及性能对比较 某些情况下要求我们查出字母在字母表中的顺序,A = 1,B = 2 , C = 3, 以此类推,比如这道题目 https://project ...
- ubuntu下code::blocks+opengl的使用与配置
操作系统:Ubuntu 15.04 gcc version 4.9.2 opengl安装 sudo apt-get install build-essential libgl1-mesa-dev li ...
- 《java中异常和错误》
异常和错误的区别. 异常: 在Java中程序的错误主要是语法错误和语义错误,一个程序在编译和运行时出现的错误我们统一称之为异常,它是VM(虚拟机)通知你的一种方式,通过这种方式,VM让你知道,你(开发 ...
- PLS入门
PLS入门: 1,两篇关键文章 [1] de Jong, S. "SIMPLS: An Alternative Approach to Partial Least Squares Regre ...
- php大力力 [049节] php函数implode()
implode()[1] 函数返回一个由数组元素组合成的字符串. 注释:implode() 函数接受两种参数顺序.但是由于历史原因,explode() 是不行的,您必须保证 separator 参数 ...
- loadRunner录制脚本常见问题及解决方法
1.是用IE9录制IE浏览器异常关闭 系统:win7 LR:11 浏览器:IE9 lr使用IE9录制脚本时,浏览器异常关闭且lr报the recording of the application wa ...