??xml version="1.0" encoding="utf-8" standalone="yes"?> // multimaptest.cpp : 定义控制台应用程序的入口炏V?br />
// #include "stdafx.h" struct userdevice{ d2.m_deviceid = "23622344";
d4.m_deviceid = "43622344"; USERTABLE m_user; m_user.insert(make_pair("zhangsanfeng2",d3)); lower_bound() ?upper_bound()Qlower_bound(k) 查找W一个与?k 兌的|?
upper_bound(k) 是查扄一个键值比 k 大的元素。下面的例子C?
upper_bound()来定位第一个其键值大于?13.108.96.7”的元素。通常Q当键是一个字W串Ӟ会有一个词典编U比较: 如果你想昄其后所有的|可以用下面这L循环Q?
l论
#include <iostream>
using namespace std;
int main()
{
multimap<string,string>mymap;
mymap.insert(multimap<string,string>::value_type("ho","123"));
mymap.insert(multimap<string,string>::value_type("hu","234"));
mymap.insert(multimap<string,string>::value_type("lian","345"));
mymap.insert(multimap<string,string>::value_type("ho","555"));
mymap.insert(multimap<string,string>::value_type("hu","444"));
mymap.insert(multimap<string,string>::value_type("ho","333"));
int num=mymap.count("ho");
switch(num)
{
case 0:
break;
case 1:
break;
default:
{
multimap<string,string>::iterator i;
pair< multimap<string,string>::iterator, multimap<string,string>::iterator>pos;
pos=mymap.equal_range("ho");
for(i=pos.first;i!=pos.second;i++)
{
cout<<i->second <<endl;
}
}
break;
}
return 0;
}
输出
123
555
333
]]>
#include <iostream>
#include <string>
#include <map>
using namespace std;
string m_devicename;
string m_deviceid;
int m_devicePopedom;
};
typedef multimap<string,userdevice> USERTABLE;
typedef USERTABLE::const_iterator CIT;
typedef pair<CIT, CIT> Range;
int _tmain(int argc, _TCHAR* argv[])
{
CIT it;
userdevice d1,d2,d3,d4;
d1.m_deviceid = "12341234";
d1.m_devicename = "d1";
d1.m_devicePopedom = 123;
d2.m_devicename = "d2";
d2.m_devicePopedom = 234;
d3.m_deviceid = "3451234";
d3.m_devicename = "d3";
d3.m_devicePopedom = 345;
d4.m_devicename = "d4";
d4.m_devicePopedom = 456;
m_user.insert(make_pair("zhangsanfeng",d1));
m_user.insert(make_pair("zhangsanfeng",d2));
m_user.insert(make_pair("zhangsanfeng2",d4));
//查找Ҏ一
Range range=m_user.equal_range("zhangsanfeng");
for(CIT i = range.first;i!=range.second;i++)
{
cout << i->second.m_deviceid<<','
<< i->second.m_devicename<<','
<<i->second.m_devicePopedom
<< endl;
}
cout<<endl;
//查找Ҏ?br />
CIT it2 = m_user.find("zhangsanfeng2");
while(it2 != m_user.end())
{
cout<<it2->second.m_deviceid<<','
<<it2->second.m_devicename<<','
<<it2->second.m_devicePopedom<<','
<<endl;
it2++;
}
cout<<endl;
//遍历
CIT it3 = m_user.begin();
while(it3 != m_user.end())
{
cout<<it3->second.m_deviceid<<','
<<it3->second.m_devicename<<','
<<it3->second.m_devicePopedom<<','
<<endl;
it3++;
}
cin.get();
return 0;
}dns.insert(make_pair("219.108.96.70", "pythonzone.com"));
CIT cit=dns.upper_bound("213.108.96.7");
if (cit!=dns.end()) //found anything?
cout<<cit->second<<endl; //display: pythonzone.com// 插入有相同键的多个?br />dns.insert(make_pair("219.108.96.70","pythonzone.com"));
dns.insert(make_pair("219.108.96.70","python-zone.com"));
// 获得W一个值的q代指针
CIT cit=dns.upper_bound("213.108.96.7");
// 输出: pythonzone.comQpython-zone.com
while(cit!=dns.end())
{
cout<<cit->second<<endl;
++cit;
}
虽然 map ?multimap h相同的接口,光要差别在于重复键Q设计和使用要区别对待。此外,q要注意每个容器?insert()成员函数的细微差别?/p>
myset.insert("Hello");
myset.insert("Hello");
myset.insert("Hou");
set<string>::iterator ite=myset.begin();
for(;ite!=myset.end();ite++)
cout<<(*ite)<<endl;
输出Hello Hou
ite=myset.begin();
myset.insert(ite,"World");
cout<<(*ite)<<endl;
输出Hello---说明没有替换W一个位|的键?br />
map 中键/值对构成好比一个地址和电话号码,以h名ؓ键|相反地set 只是键的集合?/p>
mymap.insert(map<string,int>::value_type("nihao",3));//量使用q种方式?br />
cout<<mymap["nihao"]<<endl;
mymap.insert(map<string,int>::value_type("nihao",4));
cout<<mymap["nihao"]<<endl;Q-Q-依旧输出3Q这说明如果已经有了一个键|是不能再输入的?br /> cout<<mymap.count("nihao")<<endl;Q-Q输?Q实际上只会??q两U可能?br />
但是只有当map 中存在这样一个键的实例时Q该代码才会表现正常。如果不存在q样的实例,使用下标?strong>作符会引h入一个实例?/strong>
int count=mymap.count("hou");
if(count!=0)、、只有得到count不是0Ӟ才可以安全操作?br /> cout<<mymap["hou"]<<endl;
map<string,int>::iterator ite=mymap.find("hou");
if(ite!=mymap.end())
cout<<(*ite).first<<"----"<<(*ite).second<<endl;
cout<<mymap["ri"]<<endl;Q-Q-注意Qmap里没有riq个键|因此会增加一个?br />
STL QStandard Template Library 标准模板库)是CQ+标准库的一个重要组成部分,它由Stepanov and Lee{h最先开发,它是与CQ+几乎同时开始开发的Q一开始STL选择了Ada作ؓ实现语言Q但Ada有点不争气,最后他们选择了CQ+Q一个原因了Q?CQ+中已l有了模ѝ在后来QSTL又被dq了CQ+库?996q_惠普公司又免费公开了STLQؓSTL的推q做了很大的贡献?/span>
STL大体上包括containerQ容器)、algorithmQ算法)和iteratorQP代器Q,容器和算法通过q代器可以进行无~连接。 ?/span>
STL体现?span class="GramE">?/span>型编E的思想Q它h高度的可重用性,高性能Q高UL性。程序员不用思考具体实现过E,只要能够熟练的应用就OK了。(有兴研I具体实现的Q可以看侯捷老师~著的《STL源码剖析》)q样他们可以把_֊攑֜E序开发的别的斚w?/span>
我非怽服创造STL的那些计机和数学精英。因Z们做了一仉常辛苦的事情?span class="GramE">―?/span>?象概c而STL是通过把容器抽象ؓl一的接口,法利用q个接口Q通过q代器来操纵容器。因为接口不变,实现的容器可以随意更攏V这P׃ؓ~程、调 试和扩展提供了便利。也许有一天,我们生软g的时候也可以想DIY一台PC一L单,只要拿来相应的实现模块,通过单的D和调试就可以创造一个Y 件。这是多么o人兴奋的一件事^_^.不过Q到时候,可能会有很多E序员失业了。呵呵,毕竟~写cd?/span>需要很多的人员?/span>
虽然STL不是面向对象的,但,我想Q每个h都会为它的创造力和高性能而感到兴奋和折服?/span>
一、容器?
作ؓSTL的最主要l成部分Q-容器Q分为向量(vectorQ,双端队列(deque)Q表(list)Q队列(queueQ,堆栈(stack)Q集?set)Q多重集?multiset)Q映?map)Q多重映?multimap)?/span>
容器 |
Ҏ?/span> |
所在头文g |
向量vector |
可以用常数时间访问和修改L元素Q在序列Nq行插入和删除时Q具有常数时间复杂度Q对L的插入和删除就有的旉复杂度与到末距离成正比,其对向量头的添加和删除的代h惊h的高?/span> |
<vector> |
双端队列deque |
基本上与向量相同Q唯一的不同是Q其在序列头部插入和删除操作也具有常量时间复杂度 |
<deque> |
?span lang="EN-US">list |
对Q意元素的讉K与对两端的距L正比Q但Ҏ个位|上插入和删除一个项的花费ؓ常数旉?/span> |
<list> |
队列queue |
插入只可以在Nq行Q删除、检索和修改只允总头部q行。按照先q先出的原则?/span> |
<queue> |
堆栈stack |
堆栈是项的有限序列,q满_列中被删除、检索和修改?span class="GramE">只?/span>是最q插入序列的V即按照后进先出的原?/span> |
<stack> |
集合set |
p点组成的U黑树,每个节点都包含着一个元素,节点之间以某U作用于元素对的谓词排列Q没有两个不同的元素能够拥有相同的次序,h快速查扄功能。但是它是以牺牲插入车删除操作的效率ZL |
<set> |
多重集合multiset |
和集合基本相同,但可以支持重复元素具有快速查找能?/span> |
<set> |
映射map |
由{键,值}对组成的集合Q以某种作用于键对上的谓词排列。具有快速查找能?/span> |
<map> |
多重集合multimap |
比v映射Q一?span class="GramE">键可?/span>对应多了倹{具有快速查找能?/span> |
<map> |
考虑C同的实际需要,更主要的是效率的需要,我们可以选择不同的容器来实现我们的程序,以此辑ֈ我们提高性能的目的。这也是用好STL的一个难点,但这也是关键?/span>
二、算?/strong>
?法部分主要由头文?lt;algorithm>Q?lt;numeric>?lt;functional>l成?lt; algorithm>是所有STL头文件中最大的一个,它是׃大堆模版函数l成的,可以认ؓ每个函数在很大程度上都是独立的,其中常用到的功能?围涉及到比较、交换、查找、遍历操作、复制、修攏V移除、反转、排序、合q等{?lt;numeric>体积很小Q只包括几个在序列上面进行简?数学q算的模板函敎ͼ包括加法和乘法在序列上的一些操作?lt;functional>中则定义了一些模板类Q用以声明函数对象?/span>
STL的算法也是非怼U的,它们大部分都是类属的Q基本上都用CCQ+的模板来实现Q这 P很多怼的函数就不用自己写了Q只要用函数模板OK了?/span>
我们使用法的时候,要针对不同的容器Q比如:寚w合的查找Q最好不要用通用函数findQ?span class="GramE">Q?/span>Q它寚w合用的时候,性能非常的差Q最好用集合自带的findQ?span class="GramE">Q?/span>函数Q它针对了集合进行了优化Q性能非常的高?/span>
三、P代器
它的具体实现?lt;itertator> 中,我们完全可以不管q代器类是怎么实现的,大多数的时候,把它理解为指针是没有问题的(指针是P代器的一个特例,它也属于q代器)Q但是,决不能完全这么做?/span>
q代器功?/span> Q?span lang="EN-US">Abilities Of IteratorGategoriesQ?/span> |
||
输入q代?/span> Input iterator |
向前?/span> Reads forward |
istream |
输出q代?/span> Output iterator |
向前?/span> Writes forward |
ostream,inserter |
前向q代?/span> Forward iterator |
向前d Read and Writes forward |
|
双向q代?/span> Bidirectional iterator |
向前向后d Read and Writes forward and backward |
list,set,multiset,map,mul timap |
随机q代?/span> Random access iterator |
随机d Read and Write with random access |
vector,deque,array,string |
每种容器不是万能的,不能一好百好。比如说Q多集在查找斚w的优势是其他序列容器不可比拟的?span lang="EN-US"> q有Q最好不要试图超STLQ因为:
1、STL实现使用的是最佳算法。它是几乎完的?
2、STL实现的设计者通常是相应领域的专家?
3、各领域的专家致力于提供灉|的、强大和高效的库。这是他们的首要的Q务。对于,我们q些其余的hQ开发可重用的容器和法多只算W二个目标。我们的首要d是交付紧扣主题的应用E序。大多数情况下,我们没有旉和专门的技术去和那些专家相比?/span>
?是,越STL不是不可能的。但是一般情况下Q你只能靠牺牲可UL性来提高性能Q这对于很多情况来说是很不好的。ؓ了,越STLQ我们要付出非常大的?力。而且Q最好我们知道一些STL专家们不知道的东西,后我们可以有针Ҏ的q行优化Q否则,我们的努力完全有可能白费?
面对q样一个优U的库Qƈ且它是免费的。我们C++E序员没有理由拒l它Q甚臛_自己开发一个库?/span>