===什么vector容器查找找速度最快

2016年1月 总版技术专家分月排行榜第二2015年11月 总版技术专家分月排行榜第二2015年10月 总版技术专家分月排行榜第二
优秀小版主
2015年3月 .NET技术大版内专家分月排行榜第三2015年2月 .NET技术大版内专家分月排行榜第三
2016年10月 .NET技术大版内专家分月排行榜第一2016年8月 .NET技术大版内专家分月排行榜第一2016年7月 .NET技术大版内专家分月排行榜第一
2016年12月 .NET技术大版内专家分月排行榜第二2016年9月 .NET技术大版内专家分月排行榜第二2016年6月 .NET技术大版内专家分月排行榜第二2016年3月 .NET技术大版内专家分月排行榜第二2016年1月 .NET技术大版内专家分月排行榜第二2015年12月 .NET技术大版内专家分月排行榜第二2015年2月 .NET技术大版内专家分月排行榜第二2015年1月 .NET技术大版内专家分月排行榜第二2014年11月 .NET技术大版内专家分月排行榜第二2014年5月 .NET技术大版内专家分月排行榜第二2014年4月 .NET技术大版内专家分月排行榜第二2012年2月 多媒体/设计/Flash/Silverlight 开发大版内专家分月排行榜第二
2013年5月 总版技术专家分月排行榜第一
2016年7月 总版技术专家分月排行榜第二2016年3月 总版技术专家分月排行榜第二2015年12月 总版技术专家分月排行榜第二2014年8月 总版技术专家分月排行榜第二2014年7月 总版技术专家分月排行榜第二2013年6月 总版技术专家分月排行榜第二
匿名用户不能发表回复!|
每天回帖即可获得10分可用分!小技巧:
你还可以输入10000个字符
(Ctrl+Enter)
请遵守CSDN,不得违反国家法律法规。
转载文章请注明出自“CSDN(www.csdn.net)”。如是商业用途请联系原作者。您的举报已经提交成功,我们将尽快处理,谢谢!
1.南美洲的牛虻,每小时可飞720公里
2.无脊椎动物中游泳最快的是乌贼,它的游泳速度是每秒15 米,最大速度每小时150公里,被称为“水中火箭”。
猎豹是奔跑最快的哺乳动物,每小时可达120公里。以羚羊等中、小型动物为食。除以高速追击的方式进行捕食外,也采取伏击方法,隐匿在草丛或灌木丛中,待猎物接近时突然窜...
跑得最快的动物猎豹每小时可跑145公里。
在三万多种鱼中,论游泳速度,冠军是旗鱼。旗鱼在辽阔的海域中疾驰如箭,游速每小时达120公里,比轮船的速度还要快三四...
答: 如果完全不吃肉,你需要吃更多的主食才能把蛋白质补上,而且植物蛋白的利用率往往不如动物蛋白那么高
大家还关注Everything:速度最快的文件名搜索工具(201604更新) | 善用佳软
Everything:速度最快的文件名搜索工具(201604更新)
作者:   日期:   分类: ,    标签:
2016.04 更新:v1.4 beta 添加了文件预览功能。
Everything V1.3.3.653b发布:增加64位版本;增加Home页;增加运行历史;增加最新变化。
简体中文语言包同步更新。
下载链接:
Everything(||)是速度最快的文件名搜索软件。其速度之快令人震惊,百G硬盘几十万个文件,可以在几秒钟之内完成索引;文件名搜索瞬间呈现结果。它小巧免费,支持中文,支持正则表达式,可以通过HTTP或FTP分享搜索结果。如果不满意Windows自带的搜索工具、、Google 桌面搜索或百度硬盘搜索,如果正在使用或放弃了Locate32,都值得推荐这款体积小巧、免安装、免费、速度极快(比Locate32更快)的文件搜索工具Everything!
【相关链接】、、、
【本文目录】
一、Everything简介
Everything是()开发的一款文件搜索工具,官网描述为“基于名称实时定位文件和目录(Locate files and folders by name instantly)”。它体积小巧,界面简洁易用,快速建立索引,快速搜索,同时占用极低的系统资源,实时跟踪文件变化,并且还可以通过http或ftp形式分享搜索。
– 只搜索文件名,不能搜索文件内容;
– 只适用NTFS文件系统,不适合FAT32;
– 完美支持中文(自V1.2.x开始)。
二、初级教程:Everything的基本用法
2.1 下载与安装
下载链接:
(无论下载Everything还是其他任何软件,都推荐到官方网站)
版本选择:
普通用户推荐稳定版:Everything-1.2.1.371
高级用户可下载最新测试版:
安装或解压Everything,即可开始使用。
2.2 首次运行
Everything在第一次运行时,会建立索引数据库。但你丝毫不用担心,其速度极快,生成的索引文件极小!看看本文下面的回复,你会充满信心。亲身体验之后,你或者也会为其速度震惊。或者,你根本没感觉到它需要建立索引。
索引之后,简洁的程序界面呈现在你的面前,程序状态栏中还会显示索引的文件数量。看到这个数字,你是否惊奇Everything的神速呢?
2.3 基本搜索
尽管Everything还处在英文界面,但这并不影响你的基本使用。只须在搜索框中,输入几个字母或汉字,搜索结果就会实时呈现在你的眼前。然后,可以直接双击某条结果,打开文件。也可以直接在结果中进行复制、删除等常见操作。
2.4 切换为中文界面
– 下载:xbeta简中语言包()(推荐)或官方多语言包();
– 解压:解压语言包内的Everything.lng到程序目录;
– 重启Everything(如果需要);
– 菜单:Tools→ Options→ General→ Language→ 简体中文。
说明1:官方多语言包 vs xbeta简中语言包
– 前者包括了简体中文在内的更多种语言;当然,体积更大。
– 前者的简体中文,也是来自xbeta的翻译;
– 据网友反映,前者存在默认识别为日文的bug,所以,推荐xbeta自行发布的简中语言包;
– 后者更新更加及时。
切换语言后,需要重启Everything才能看到效果。而点击Everything窗口的关闭按钮后,它只是缩小为托盘图标,并没有真正关闭,所以,要右键退出。
2.5 视频演示
视频Flash演示:(Wink录制,500×320, 126KB)
三、Everything搜索技巧
3.1 高效搜索之“与”“或”
技巧:在Everything的搜索框中可以输入多个关键词,以空格分开,表示搜索结果要包括全部关键词。大家肯定对这种做法不会陌生,因为它正是搜索引擎的惯例。
举例:键入(不包括引号,下同)“李白 北京 08 jpg”,可以快速找出某些照片。
技巧:对应“与”的还有“或”(OR)运算,用半角竖线表示:|。当你不确信关键词的准确描述时,这种方式非常有用。
举例:“jpg 李白|libai 北京 08”、“免费|freeware”……
引伸:既然空格表示“与”,那么如何表示真正的空格呢?很简单,加英文半角引号,比如”program files”。
3.2 正则表达式
Everything支持正则表达式,或者说,支持一些简单的正则表达式。但对大多数用户而言,这已经足够了!Everything支持的正则表达式有:
| () ? * + . [] [^] ^ $ {m,n}
详见官方FAQ(|)。鸣谢朱晨刚、。
3.3 指定搜索范围
默认情况下,Everything索引、搜索所有本地NTFS磁盘的所有目录。但是你可以通过如下方式,限定搜索范围,以得到更易用的结果列表。
– 希望Everything永不索引某个磁盘,请在“选项”-“NTFS磁盘”中,选定相应盘符,取消“搜索本卷”或“包含在数据库中”。(注:可以取消前一项,这样后一项就自动变灰——但没发现这种做法与只取消后一项的差别。大家可以研究一下!)
– 希望永远排除某些目录,可以在“选项”-“排除列表”中设定。和上条方法一样,确认之后Everything会重新生成索引。
– 希望Everything只搜索某个目录,可以在资源管理器或Total Commander中,右击该目录,在弹出菜单上选“Search Everything…”。这时你会看到Everything的搜索框中,出现了带引号的目录名。
– 与上一方法相同,只是不用右击目录,而是直接输入带引号的目录名,再输入搜索关键词。需要注意的是:目录名一定是完整路径,且用半角双引号括起来,不能选中“使用正则表达式”。
– 还有一种方法,使用起来要头脑更清楚才行。比如,设定“匹配路径”后,输入 files/ .exe,看看搜到了什么结果,想想这是为什么。
3.4 网络分享
Everything内置了HTTP、ETP/FTP服务器。这意味着,你可以用它当作简单的服务器来用。何况,它的HTTP分享,仍然提供了强大的搜索功能。
HTTP分享:点击菜单“工具”-“HTTP服务器”后,就可以在浏览器访问 http://localhost 或输入本机IP进行访问了。在HTTP中,它的搜索功能一样强大。因此,你可以把它加入Firefox等浏览器的自定义搜索中,更加方便的进行搜索。
FTP功能类似,但不具备搜索功能。
相比而言,因为浏览器更为常用,并且支持搜索,默认的UTF-8编码识别率更高,所以推荐HTTP方式分享。无论是HTTP还是FTP,其端口、用户名、密码都是可以设定的。这样,你就可以在局域网内更放心的分享文件了。
除了与朋友分享之外,在文件服务器上运行Everything,然后用户就可以通过浏览器快速搜索了。这是一个很好的应用。
3.5 查找重复文件
在搜索框中输入 dupe: 可以搜索重复文件。在冒号后面可以添加其他关键词,来限定文件名称、文件类型(比如 mp4, docx……)
但务必注意,「重复文件」的定义!Everything 作为文件名称搜索工具,重复的定义就是文件名相同。当然,你可以借助文件大小、修改日期来做进一步的判定,但删除之前仍须谨慎!
比如,下图中 Everything 显示了多条重复文件,但实际上只有黄色标示的 2 个文件,才是真正重复的。
如果需要更精准的查找,我会使用 Total Commander 的查找重复功能,对「重复」做出自己的定义,之后再执行搜索。比如,下例是查找重复照片:它们的名称未必相同,但文件大小相同,为了防止误报,又添加了一条规则「相机在生成数码照片时的时间戳」必须相同。
如果有更多需求,请参阅
四、Everything与其他程序集成
Everything如此好用,所以很多网友探索了它与其他程序的集成方法,汇总如下。个人观点是,Everything与TC的集成具有很高实用性;另外几种集成可供参考和启发。
4.1 Everything与Total Commander集成
a. 双向集成的目标
所谓Everything与Total Commander集成,到底指什么?善用佳软的实际使用中,实现了如下双向集成:
① 从TC到Everything:在Total Commander中,按下ctrl+alt+f则打开Everything进行搜索;
② 从Everything到TC:在Everything搜索结果上,双击目录,或在文件上右键菜单“打开路径”,则Total Commander进入此目录。需要说明的是,目前TC只能打开该目录,但不能自动选中搜索结果。
b. 从TC到Everything的集成方法
依靠自己:“自己动手,丰衣足食”,虽然效率不一定高,但这是最可靠的方法,即利用Total Commander的标准功能调用Everything。其实现手段有多种,原理和视频操作可参见《TC学堂》中《》中相关内容,比如“4. 外部程序化为TC扩展命令”。
依靠TC作者:最理想的方案当然是,TC作者针对Everything提供专门的、更优的集成方案。但是,坚持自己原则的Ghisler认为:尽管Everything效率极高,但由于NTFS格式限制,不具有通用性,所以,不会官方集成。
依靠雷锋叔叔:除了TC作者,你还会期望网络上某个热心人开发一款相应插件。果然,俄罗斯网友为TC开发了FSE插件。优点:可以把搜索结果输出到TC的窗口里面处理。缺点:目前仅支持ASCII字符,即不支持中文。(作者表示,将在 Locate 支持Unicode之后,修复此bug。)所以,最终结论是:中文用户暂不推荐。
c. 从Everything到TC的集成方法
以下内容由网友dracodoc于 1:17补充。
这次更新不仅仅是语言包,更重要的是可以支持其他文件管理器,已经可以和total commander集成了。有介绍。
我的修改:
explore_folder_command=$exec(“%SystemRoot%explorer.exe” /n,/e,+)
explore_folder_path_command=$exec(“%SystemRoot%explorer.exe” /n,/e,/select,+)
open_folder_path_command=$exec(“d:appwincmdTOTALCMD.EXE” “$parent(%1)”)
open_file_command=$exec()
open_folder_command=$exec(“d:appwincmdTOTALCMD.EXE” )
explore部分不用变,保留第二种选择。需要在tc里设定只打开一个tc实例,我试过用tc命令行的/o参数来不打开第二个实例,但是everything不认。
现在双击找到的文件会打开,双击目录会激活tc跳到该目录(如果你想设定在左边,右边或者新建一个tab可以尝试加上tc的命令行参数,不一定能用),右键选择文件,open path会用tc打开文件所在目录。
再在tc里或者其他全局hotkey设定程序里设定everything的激活热键就可以了(我不喜欢一直开着,随用随启动并不慢)
需注意的是,上述功能只适用于v1.2.0.323b及以后版本,请检查你的程序,或最新beta版。低版本Everything无法识别上述ini内容,会强行删除。“在tc里设定只打开一个tc实例”的做法有2种。一是图形化操作(推荐):配置 → 操作方式 → 主程序 → 只允许一个TC运行。二是直接在wincmd.ini中的[Configuration]段增加一句 onlyonce=1,并重启TC。
4.2 Everything代替Windows默认搜索
Windows自带的搜索程序功能不错,但速度偏慢。如果你希望把“开始”菜单中的搜索替换为Everything(或其他搜索软件),可以用修改工具进行设置。软件小巧,使用容易,、、先后都有介绍,此处从略。
4.3 Everything与Firefox集成
因为Everything自带了HTTP服务器功能——当然也拥有同样出色的搜索功能——因此,可以通过浏览器进行本地或网络计算机的搜索。当然,有一个前提:搜索目标机上Everything一直打开并且启用HTTP服务器。如果认为输入网址不方便,也可以集成的到浏览器的搜索框中。比如,Firefox可通过扩展加入到工具栏的搜索框引擎(可设定用户名/密码以保护安全),详见文章。
五、其他补充
5.1 everything的速度
Everything搜索工具的最大优点是速度。其速度不是快,是极快;用户不是满意,而是震惊。
第一个快速体现在索引速度。官网称,1分钟可索引100万个文件。笔者的NTFS文件系统共40G/近4万个文件,第一次启动时,根本没有感觉到建立索引需要时间。这种快速,是因为Everything的索引无需逐一扫描硬盘文件,而是直接读取NTFS文件系统的USN日志。这当然是既省力,又合理的做法。
第二个快速体现在搜索速度。在搜索框中键入字符后,搜索结果——或许称为过滤结果更准确——实时呈现。
总起来看,多篇测评和试用者认为,其速度超过了以前备受好评的。是否真有这么快?请各位读者反馈试用结果。目前收到的反馈都证明了这一点,对有些网友而言,速度已经快到令人震惊,甚至是愤怒了:凭什么可以这么快!
5.2 Everything资源占用
总起来讲,占用资源很少。
– 从安装(实际解压即可)来看,真正需要的只有一个主文件exe,约0.5MB。
– 索引数据库极小。笔者60G硬盘,索引文件0.7MB。
– 占用内存少,笔者使用为7MB。
5.3 Everything数据库更新
– 没有所谓更新频率的设定,因为更新是自动的。
– 每次重启Everything,都会自动更新;
– 每次设置Everything(比如设定排除列表)之后,都会自动更新;
– Everything运行时,会实时更新索引数据库。
5.4 Everything与windows管理员权限问题
问题1:非管理员用户,如何使用Everything?
Everything的运行需要管理员权限 。但有时出于安全考虑,不应该(或不能)以管理员身份登录Windows。如何解决这一冲突呢?
思路1:权限法:
“解铃还须系铃人”。如果认为此问题是windows的权限问题,则需要寻找通用的权限解决方案。比如:
– Windows系统具备的run as。
– 第3方软件,如 RunasSpc:;
– 第3方软件,如 CPAU:、。
思路2:服务法:
“解铃还须系铃人”。如果认为此问题是Everything的问题,则请到官方论坛搜索答案、向最新beta版寻求答案。论坛中:未来或许可以通过服务来解决。而的更新说明中显示:此功能已具备(added service parameters option)。
下载v1.2.1.451a,关闭目前运行的Everything。稳妥起见,不妨也把其他db、xml、ini文件删除,即从零开始一个Everything程序。
然后,运行 d:\soft\everything\Everything.exe -install_service ,就会增加Everything对应的服务了。说明:我在WinXP下,试图以非管理员身份运行 d:\soft\everything\Everything.exe -install_service ,似乎未成功安装服务——请大家帮助再次确认。
(善用佳软于再次测试通过,WinXP SP2,Everything v1.2.1.451a)
以管理员身份运行Everything后,在搜索结果中双击exe运行其他程序,会继承管理员权限。如何避免?
暂无办法。
Win7下面不能自启动的问题。
不太了解,欢迎其他网友补充。
如果你经常需要按照文件名进行快速搜索,并且磁盘用了NTFS文件系统,则Everything是首荐工具。如果你需要远程搜索其他计算机上的文件,那么Everything的服务器共享功能更为适合。总之,这款不到1MB的搜索利器,很值得收藏试用。
1. 一个好软件是如何被大众了解的?
我一直对此传播过程充满好奇。我看到的Everything传播是这样的:lifehacker于9月25日发文介绍;网友读过上文后于26日在论坛发文;10月25日左右我读了DC文章并访问官网、联系作者并于10月28日得到作者回复。然后,11月1日freewaregenius发表了,簡睿隨筆 《科技篇》读过上文后于11月2日写了()。于是,我也在翻译完成之前先发此文,以便合力宣传everything。
其他网友的介绍文章:
* 電腦玩物:
* 小众软件:
* 异次元世界:
2. 补充两款水木社区网友原创的同类软件
cygwin的,和bbinn的,这两位都是我很敬佩的高手。两款软件也是的关系,都是小巧、免费的佳作。bbinn还有一款文件查重小软件FindDump,也在上面的贴子中。
3. 文章更新记录
:增加最新中文语言包。
:增加Everything运行时关于管理员权限问题。
:补充Everything与其他程序的集成;为本文增加目录。
:软件升级到Everything-1.2.1.358b,提供了新选项:搜索时指定排除目录及文件(支持通配符)。同步更新了 。
:v1.2beta发布,Everything 集成Total Commander,真好!
:补入其他网友的相关介绍链接
:语言包已由官方发布;善用佳软提供语言包txt文本,供有兴趣者参考和改进。
:更新语言包,更新本文30%内容;
(<span id="cos_support-个)下次自动登录
现在的位置:
& 综合 & 正文
STL 容器简介:C++ 容器:顺序性容器、关联式容器和容器适配器
标准容器类
顺序性容器
从后面快速的插入与删除,直接访问任何元素
从前面或后面快速的插入与删除,直接访问任何元素
双链表,从任何地方快速插入与删除
快速查找,不允许重复值
快速查找,允许重复值
一对多映射,基于关键字快速查找,不允许重复值
一对多映射,基于关键字快速查找,允许重复值
容器适配器
priority_queue
最高优先级元素总是第一个出列
所有标准库共有函数
默认构造函数
提供容器默认初始化的构造函数。
复制构造函数
将容器初始化为现有同类容器副本的构造函数
不再需要容器时进行内存整理的析构函数
容器中没有元素时返回true,否则返回false
返回容器中最大元素个数
返回容器中当前元素个数
将一个容器赋给另一个容器
如果第一个容器小于第二个容器,返回true,否则返回false,
operator&=
如果第一个容器小于或等于第二个容器,返回true,否则返回false
如果第一个容器大于第二个容器,返回true,否则返回false
operator&=
如果第一个容器大于或等于第二个容器,返回true,否则返回false
operator==
如果第一个容器等于第二个容器,返回true,否则返回false
operator!=
如果第一个容器不等于第二个容器,返回true,否则返回false
交换两个容器的元素
其中operator&,operator&=,operator&,operator&=,operator==,operator!=均不适用于priority_queue
顺序容器和关联容器共有函数
该函数两个版本返回iterator或const_iterator,引用容器第一个元素
该函数两个版本返回iterator或const_iterator,引用容器最后一个元素后面一位
该函数两个版本返回reverse_iterator或const_reverse_iterator,引用容器最后一个元素
该函数两个版本返回reverse_iterator或const_reverse_iterator,引用容器第一个元素前面一位
从容器中清除一个或几个元素
清除容器中所有元素
下表显示了顺序容器和关联容器中常用的typedef,这些typedef常用于变量、参数和函数返回值的一般性声明。
value_type
容器中存放元素的类型
容器中存放元素类型的引用
const_reference
容器中存放元素类型的常量引用,这种引用只能读取容器中的元素和进行const操作
容器中存放元素类型的指针
指向容器中存放元素类型的迭代器
const_iterator
指向容器中存放元素类型的常量迭代器,只能读取容器中的元素
reverse_iterator
指向容器中存放元素类型的逆向迭代器,这种迭代器在容器中逆向迭代
const_reverse_iterator
指向容器中存放元素类型的逆向迭代器,只能读取容器中的元素
difference_type
引用相同容器的两个迭代器相减结果的类型(list和关联容器没有定义operator-)
用于计算容器中项目数和检索顺序容器的类型(不能对list检索)
什么是容器
首先,我们必须理解一下什么是容器,在C++ 中容器被定义为:在数据存储上,有一种对象类型,它可以持有其它对象或指向其它对像的指针,这种对象类型就叫做容器。很简单,容器就是保存其它对象的对象,当然这是一个朴素的理解,这种“对象”还包含了一系列处理“其它对象”的方法,因为这些方法在的设计上会经常被用到,所以容器也体现了一个好处,就是“容器类是一种对特定重用问题的良好的解决方案”。
容器还有另一个特点是容器可以自行扩展。在解决问题时我们常常不知道我们需要存储多少个对象,也就是说我们不知道应该创建多大的内存空间来保存我们的对象。显然,数组在这一方面也力不从心。容器的优势就在这里,它不需要你预先告诉它你要存储多少对象,只要你创建一个容器对象,并合理的调用它所提供的方法,所有的处理细节将由容器来自身完成。它可以为你申请内存或释放内存,并且用最优的来执行您的命令。
容器是随着面向对象语言的诞生而提出的,容器类在面向对象语言中特别重要,甚至它被认为是早期面向对象语言的基础。在现在几乎所有的面向对象的语言中也都伴随着一个容器集,在C++ 中,就是标准模板库(STL )。
和其它语言不一样,C++ 中处理容器是采用基于模板的方式。标准C++ 库中的容器提供了多种数据结构,这些数据结构可以与标准算法一起很好的工作,这为我们的软件开发提供了良好的支持!
通用容器的分类
STL 对定义的通用容器分三类:顺序性容器、关联式容器和容器适配器。
顺序性容器 是一种各元素之间有顺序关系的线性表,是一种线性结构的可序群集。顺序性容器中的每个元素均有固定的位置,除非用删除或插入的操作改变这个位置。这个位置和元素本身无关,而和操作的时间和地点有关,顺序性容器不会根据元素的特点排序而是直接保存了元素操作时的逻辑顺序。比如我们一次性对一个顺序性容器追加三个元素,这三个元素在容器中的相对位置和追加时的逻辑次序是一致的。
关联式容器 和顺序性容器不一样,关联式容器是非线性的树结构,更准确的说是二叉树结构。各元素之间没有严格的物理上的顺序关系,也就是说元素在容器中并没有保存元素置入容器时的逻辑顺序。但是关联式容器提供了另一种根据元素特点排序的功能,这样迭代器就能根据元素的特点“顺序地”获取元素。
关联式容器另一个显著的特点是它是以键值的方式来保存数据,就是说它能把关键字和值关联起来保存,而顺序性容器只能保存一种(可以认为它只保存关键字,也可以认为它只保存值)。这在下面具体的容器类中可以说明这一点。
容器适配器 是一个比较抽象的概念, C++的解释是:适配器是使一事物的行为类似于另一事物的行为的一种机制。容器适配器是让一种已存在的容器类型采用另一种不同的抽象类型的工作方式来实现的一种机制。其实仅是发生了接口转换。那么你可以把它理解为容器的容器,它实质还是一个容器,只是他不依赖于具体的标准容器类型,可以理解是容器的模版。或者把它理解为容器的接口,而适配器具体采用哪种容器类型去实现,在定义适配器的时候可以由你决定。
下表列出STL 定义的三类容器所包含的具体容器类:
标准容器类
顺序性容器
从后面快速的插入与删除,直接访问任何元素
从前面或后面快速的插入与删除,直接访问任何元素
双链表,从任何地方快速插入与删除
快速查找,不允许重复值
快速查找,允许重复值
一对多映射,基于关键字快速查找,不允许重复值
一对多映射,基于关键字快速查找,允许重复值
容器适配器
priority_queue
最高优先级元素总是第一个出列
顺序性容器
向量 vector :
是一个线性顺序结构。相当于数组,但其大小可以不预先指定,并且自动扩展。它可以像数组一样被操作,由于它的特性我们完全可以将vector 看作动态数组。
在创建一个vector 后,它会自动在内存中分配一块连续的内存空间进行数据存储,初始的空间大小可以预先指定也可以由vector 默认指定,这个大小即capacity ()函数的返回值。当存储的数据超过分配的空间时vector 会重新分配一块内存块,但这样的分配是很耗时的,在重新分配空间时它会做这样的动作:
首先,vector 会申请一块更大的内存块;
然后,将原来的数据拷贝到新的内存块中;
其次,销毁掉原内存块中的对象(调用对象的析构函数);
最后,将原来的内存空间释放掉。
如果vector 保存的数据量很大时,这样的操作一定会导致糟糕的性能(这也是vector 被设计成比较容易拷贝的值类型的原因)。所以说vector 不是在什么情况下性能都好,只有在预先知道它大小的情况下vector 的性能才是最优的。
vector 的特点:
(1) 指定一块如同数组一样的连续存储,但空间可以动态扩展。即它可以像数组一样操作,并且可以进行动态操作。通常体现在push_back() pop_back() 。
(2) 随机访问方便,它像数组一样被访问,即支持[ ] 操作符和vector.at()
(3) 节省空间,因为它是连续存储,在存储数据的区域都是没有被浪费的,但是要明确一点vector 大多情况下并不是满存的,在未存储的区域实际是浪费的。
(4) 在内部进行插入、删除操作效率非常低,这样的操作基本上是被禁止的。Vector 被设计成只能在后端进行追加和删除操作,其原因是vector 内部的实现是按照顺序表的原理。
(5) 只能在vector 的最后进行push 和pop ,不能在vector 的头进行push 和pop 。
(6) 当动态添加的数据超过vector 默认分配的大小时要进行内存的重新分配、拷贝与释放,这个操作非常消耗性能。 所以要vector 达到最优的性能,最好在创建vector 时就指定其空间大小。
双向链表list
是一个线性链表结构,它的数据由若干个节点构成,每一个节点都包括一个信息块(即实际存储的数据)、一个前驱指针和一个后驱指针。它无需分配指定的内存大小且可以任意伸缩,这是因为它存储在非连续的内存空间中,并且由指针将有序的元素链接起来。
由于其结构的原因,list 随机检索的性能非常的不好,因为它不像vector 那样直接找到元素的地址,而是要从头一个一个的顺序查找,这样目标元素越靠后,它的检索时间就越长。检索时间与目标元素的位置成正比。
虽然随机检索的速度不够快,但是它可以迅速地在任何节点进行插入和删除操作。因为list 的每个节点保存着它在链表中的位置,插入或删除一个元素仅对最多三个元素有所影响,不像vector 会对操作点之后的所有元素的存储地址都有所影响,这一点是vector 不可比拟的。
list 的特点:
(1) 不使用连续的内存空间这样可以随意地进行动态操作;
(2) 可以在内部任何位置快速地插入或删除,当然也可以在两端进行push 和pop 。
(3) 不能进行内部的随机访问,即不支持[ ] 操作符和vector.at() ;
(4) 相对于verctor 占用更多的内存。
双端队列deque
是一种优化了的、对序列两端元素进行添加和删除操作的基本序列容器。它允许较为快速地随机访问,但它不像vector 把所有的对象保存在一块连续的内存块,而是采用多个连续的存储块,并且在一个映射结构中保存对这些块及其顺序的跟踪。向deque 两端添加或删除元素的开销很小。它不需要重新分配空间,所以向末端增加元素比vector 更有效。
实际上,deque 是对vector 和list 优缺点的结合,它是处于两者之间的一种容器。
deque 的特点:
(1) 随机访问方便,即支持[ ] 操作符和vector.at() ,但性能没有vector 好;
(2) 可以在内部进行插入和删除操作,但性能不及list ;
(3) 可以在两端进行push 、pop ;
三者的比较
下图描述了vector 、list 、deque 在内存结构上的特点:
vector 是一段连续的内存块,而deque 是多个连续的内存块, list 是所有数据元素分开保存,可以是任何两个元素没有连续。
vector 的查询性能最好,并且在末端增加数据也很好,除非它重新申请内存段;适合高效地随机存储。
list 是一个链表,任何一个元素都可以是不连续的,但它都有两个指向上一元素和下一元素的指针。所以它对插入、删除元素性能是最好的,而查询性能非常差;适合 大量地插入和删除操作而不关心随机存取的需求。
deque 是介于两者之间,它兼顾了数组和链表的优点,它是分块的链表和多个数组的联合。所以它有被list 好的查询性能,有被vector 好的插入、删除性能。 如果你需要随即存取又关心两端数据的插入和删除,那么deque 是最佳之选。
set, multiset, map, multimap 是一种非线性的树结构,具体的说采用的是一种比较高效的特殊的平衡检索二叉树—— 红黑树结构。(至于什么是红黑树,我也不太理解,只能理解到它是一种二叉树结构)
因为关联容器的这四种容器类都使用同一原理,所以他们核心的算法是一致的,但是它们在应用上又有一些差别,先描述一下它们之间的差别。
set ,又称集合,实际上就是一组元素的集合,但其中所包含的元素的值是唯一的,且是按一定顺序排列的,集合中的每个元素被称作集合中的实例。因为其内部是通过链表的方式来组织,所以在插入的时候比vector 快,但在查找和末尾添加上被vector 慢。
multiset ,是多重集合,其实现方式和set 是相似的,只是它不要求集合中的元素是唯一的,也就是说集合中的同一个元素可以出现多次。
map ,提供一种“键- 值”关系的一对一的数据存储能力。其“键”在容器中不可重复,且按一定顺序排列(其实我们可以将set 也看成是一种键- 值关系的存储,只是它只有键没有值。它是map 的一种特殊形式)。由于其是按链表的方式存储,它也继承了链表的优缺点。
multimap , 和map 的原理基本相似,它允许“键”在容器中可以不唯一。
关联容器的特点是明显的,相对于顺序容器,有以下几个主要特点:
1, 其内部实现是采用非线性的二叉树结构,具体的说是红黑树的结构原理实现的;
2, set 和map 保证了元素的唯一性,mulset 和mulmap 扩展了这一属性,可以允许元素不唯一;
3, 元素是有序的集合,默认在插入的时候按升序排列。
基于以上特点,
1, 关联容器对元素的插入和删除操作比vector 要快,因为vector 是顺序存储,而关联容器是链式存储;比list 要慢,是因为即使它们同是链式结构,但list 是线性的,而关联容器是二叉树结构,其改变一个元素涉及到其它元素的变动比list 要多,并且它是排序的,每次插入和删除都需要对元素重新排序;
2, 关联容器对元素的检索操作比vector 慢,但是比list 要快很多。vector 是顺序的连续存储,当然是比不上的,但相对链式的list 要快很多是因为list 是逐个搜索,它搜索的时间是跟容器的大小成正比,而关联容器 查找的复杂度基本是Log(N) ,比如如果有1000 个记录,最多查找10 次,1,000,000 个记录,最多查找20 次。容器越大,关联容器相对list 的优越性就越能体现;
3, 在使用上set 区别于vector,deque,list 的最大特点就是set 是内部排序的,这在查询上虽然逊色于vector ,但是却大大的强于list 。
4, 在使用上map 的功能是不可取代的,它保存了“键- 值”关系的数据,而这种键值关系采用了类数组的方式。数组是用数字类型的下标来索引元素的位置,而map 是用字符型关键字来索引元素的位置。在使用上map 也提供了一种类数组操作的方式,即它可以通过下标来检索数据,这是其他容器做不到的,当然也包括set 。(STL 中只有vector 和map 可以通过类数组的方式操作元素,即如同ele[1] 方式)
容器适配器
STL 中包含三种适配器:栈stack 、队列queue 和优先级priority_queue 。
适配器是容器的接口,它本身不能直接保存元素,它保存元素的机制是调用另一种顺序容器去实现,即可以把适配器看作“它保存一个容器,这个容器再保存所有元素”。
STL 中提供的三种适配器可以由某一种顺序容器去实现。默认下stack 和queue 基于deque 容器实现,priority_queue 则基于vector 容器实现。当然在创建一个适配器时也可以指定具体的实现容器,创建适配器时在第二个参数上指定具体的顺序容器可以覆盖适配器的默认实现。
由于适配器的特点,一个适配器不是可以由任一个顺序容器都可以实现的。
栈stack 的特点是后进先出,所以它关联的基本容器可以是任意一种顺序容器,因为这些容器类型结构都可以提供栈的操作有求,它们都提供了push_back 、pop_back 和back 操作;
队列queue 的特点是先进先出,适配器要求其关联的基础容器必须提供pop_front 操作,因此其不能建立在vector 容器上;
优先级队列priority_queue 适配器要求提供随机访问功能,因此不能建立在list 容器上。
一种随机访问的数组类型,他提供了对数组元素的快速、随机访问,以及在序列尾部快速、随机的插入和删除操作。它在需要时可以改变其大小,也就是说大小可变的向量,比较灵活。可取代C++语言本身提供的传统数组。提供随机存储能力。操作尾端元素的速度最快。由于所有元素占用连续空间,所以一旦进行插入或者删除动作,有可能使原本的某些 iterators失效。
这是一个双向链表容器,完成了标准的C++数据结构中链表的所有功能。它不支持随机访问的数组类型,因为STL以双向链表的方式实现list对象,所以访问链表元素要指针从链表的某个端点开始。插入和删除操作所花的时间是固定的,也就是说,list对象插入和删除一个元素所需要的时间与该元素在链表中的位置无关。在任何位置做插入和删除动作都很快,不像vector只局限于尾端,而deque只局限于两端才有高效率。由于各元素并不占用连续空间,所以一旦进行插入或者删除动作,原本的iterators任然有效。注意,许多只在元素搬移的STL
algorithms用于list身上会有不佳的效率。幸好这些STL algorithms 都有对应的list member functions 可以替代。后者之所以会有比较好的效率,原因是他们只操作指标,而非真正去拷贝或者移动元素。
这是一种队列容器,它采用deque和list对象创建一个先进先出(FIFO)的容器,它实际上完成了标准的C++数据结构中的队列所有功能。不提供随机存储能力。行为与特性都很类似vector,但因为是双向开口,所以操作两端元素的速度都很快,不像vectoer只在操作尾端元素时才有高效率。由于所有元素占用连续空间,所以一旦进行插入或者删除动作,有可能是原本的某些iterators失效。
这是一种栈容器,完成了标准的C++数据结构中栈的所有功能。也就是说,它通过vector、deque或者list对象创建了一个先进后出的容器。stack特性是先进后出(FILO: First In, Last Out)。
这是一种随机访问的数据类型,提供了在序列两端快速插入和删除操作的功能,他可以再需要的时候修改器自身大小。也就是说这是一种双端队列容器,完成了标准的C++数据结构中队列的所有功能。queue特性是先进先出。
priority_queue:
这是一种按值排序的队列容器。它使用vector或者deque对象创建了一个排序队列。priority_queue特性是依优先权来谁是下一个元素。
这是一种随机存取的集合容器。其关键词和数据元素是同一个值,也就是说它不能包含重复的元素。set经过排序的结构体,以某个可指定的排序方式排序,每个元素第一无二。由于已经排序,所以搜寻速度极快。但也因此不允许我们直接修改某个元素的内容,因为这可能会影响排序。修改元素内容的正确的作法是,先将该元素删除,再加入(此时使用新值)。set通常是以平衡二叉树(balanced binary tree)来存储(但并不是强制规定),甚至是以red-black trees来完成。
其关键词和数据元素也是同一个值,但和set不同的以及最大的区别在于这是一种允许出现重复元素的集合容器。multiset允许元素重复。
其是一种关联数组容器,它包含成对数据的容器,其中一个值是实际数据值,另外一个是用来寻找数据的关键值,一个特定的关键词只能与一个元素相关联。map是由一对一对的键值(key/value)所组成的排序结构体,键值独一无二。map通常是以balanced binary tree来实现,但并不强制规定。事实上map的内部结构通常与set是一样的,因此我们可以将set视为一种特殊的map,其键值和实值是相同的,所以map和set几乎拥有完全相同的能力。
这是一种允许出现重复关键之的关联数组容器,然而与map对象不同,它的一个关键词可以与多个元素相联系,multimap允许键值重复。
hash table:
这并不是C++ Standard规范内的一容器(因标准委员会作业时间的关系),但是它对于大量数据的搜索而言,很实用也很重要。有许多STL实作品例如SGI都涵盖了它。通常STL产品厂商会提供4中hash tables: hash_set、hash_multiset、hash_map、hash_multimap。
&&&&推荐文章:
【上篇】【下篇】

我要回帖

更多关于 vector容器查找 的文章

 

随机推荐