??xml version="1.0" encoding="utf-8" standalone="yes"?> 1. 对于兌容器(如map, set, multimap,multiset)Q删除当前的iteratorQ仅仅会使当前的iterator失效Q只要在eraseӞ递增当前iterator卛_?/span>q是因ؓmap之类的容器,使用了红黑树来实玎ͼ插入、删除一个结点不会对其他l点造成影响?/span> Set是关联容器。其键值就是实|实值就是键|不可以有重复Q所以我们不能通过set的P代器来改变set的元素的|set拥有和list相同的特性:当对他进行插入和删除操作的时候,操作之前的P代器依然有效。当然删除了的那个就没效了。Set的底层结构是RB-treeQ所以是有序的?/p>
stl中特别提供了一U针对set的操作的法Q交集set_intersectionQƈ集set_unionQ差集set_difference。对U差集set_symeetric_differenceQ这些算法稍后会讲到?/p>
一Qset模板cȝ声明?/p>
其中个参数的意义如下Q?/strong> keyQ?/strong>要放入set里的数据cdQ可以是Mcd的数据?/p>
TraitsQ?/strong>q是一个仿函数Q关于仿函数是什么,我后面的文章会讲刎ͼ。提供了h比较功能的仿函数Q来觉得元素在set里的排列的顺序,q是一个可选的参数Q默认的是std::less<key>Q如果要自己提供q个参数Q那么必要遵@此规则:h两个参数Q返回类型ؓbool?/p>
Allocator:I间配置器,q个参数是可选的Q默认的是std::allocator<key>. 二:set里的基本操作 我们可以通过下面的方法来实例化一个set?/span>?/span> std::set<int> s;那个sq个对象里面存贮的元素是从小到大排序的,(因ؓ用std::less作ؓ比较工具? 如果要想在s里面插入数据Q可以用inset函数Qset没用重蝲[]操作Q因为set本生的值和索引是相同的) s.insert(3);s.insert(5)..... 因ؓset是集合,那么集合本np求是唯一性,所以如果要像set里面插入数据和以前的数据有重合,那么插入不成功?/font> 可以通过下面的方法来遍历set里面的元?/font> 如果要查找一个元素用find函数Qit = s.find(3);q样it是指?的那个元素的。可以通过rbeginQrend来逆向遍历 q有其他的一些操作在q就不一一列出了?/font> 三:与set相关的一l算?/font> set_intersection() :q个函数是求两个集合的交?/font>。下面是stl里的源代?/p>
q是个模板函敎ͼ从上面的法可以看出Q传q去的两个容器必L有序的。_Dest指向输出的容器,q个容器必须是预先分配好I间的,否则会出错的,q回值指向保存结果的容器的尾端的下一个位|。eg.
在用eraseҎ删除元素Ӟq代器有时候会失效?/span>在Effective STLQ条?Q找Cerase容器中元素的原则?br />
错误的用方?/strong>Q?br />
std::map<string, string>::iterator iter;
for ( iter = mapTest.begin();iter != mapTest.end(); iter ++ )
{
if ( iter->second == "test" )
{
mapTest.erase( iter );
}
}
正确的用方?Q?/strong>
std::map<string, string>::iterator iter;
for ( iter = mapTest.begin();iter != mapTest.end();)
{
if ( iter->second == "test" )
{
mapTest.erase( iter++ );
}
else
{
iter++; // Use Pre Increment for efficiency.
}
}
正确的用方?Q?br />
std::map<string, string>::iterator iter;
for ( iter = mapTest.begin();iter != mapTest.end();)
{
if ( iter->second == "test" )
{
iter = mapTest.erase( iter );
}
else
{
++iter; // Use Pre Increment for efficiency.
}
}
2. 对于序列式容?如vector,deque)Q删除当前的iterator会后面所有元素的iterator都失效。这是因为vetor,deque使用了连l分配的内存Q删除一个元素导致后面所有的元素会向前移动一个位|。还?/span>eraseҎ可以q回下一个有效的iterator?/span>
3. 对于list来说Q它使用了不q箋分配的内存,q且它的eraseҎ也会q回下一个有效的iteratorQ因此上面两U正的Ҏ都可以用?/span>
其他链接Q?a href="http://www.shnenglu.com/Herbert/archive/2009/01/08/70479.html">http://www.shnenglu.com/Herbert/archive/2009/01/08/70479.html
其他链接Q?a >http://blog.csdn.net/kay226/article/details/6126515
其他链接Q?a href="http://www.shnenglu.com/humanchao/archive/2013/04/22/199630.html">http://www.shnenglu.com/humanchao/archive/2013/04/22/199630.html
]]>
q代器是一U对象,它能够用来遍历STL容器中的部分或全部元素,每个q代器对象代表容器中的确定的地址。P代器修改了常规指针的接口Q所谓P代器是一U概念上的抽象:那些行ؓ上象q代器的东西都可以叫做P代器。然而P代器有很多不同的能力Q它可以把抽象容器和通用法有机的统一h?br /> q代器提供一些基本操作符Q??+?=、!=?。这些操作和C/C++“操作array元素”时的指针接口一致。不同之处在于,q代器是个所谓的smart pointersQ具有遍历复杂数据结构的能力。其下层q行机制取决于其所遍历的数据结构。因此,每一U容器型别都必须提供自己的P代器。事实上每一U容器都其q代器以嵌套的方式定义于内部。因此各UP代器的接口相同,型别却不同。这直接导出了泛型程序设计的概念Q所有操作行为都使用相同接口Q虽然它们的型别不同?br />
功能特点
q代器开发h员不必整个实现类接口。只需提供一个P代器Q即可遍历类中的数据l构Q可被用来访问一个容器类的所包函的全部元素,其行为像一个指针,但是只可被进行增?++)或减?--)操作。D一个例子,你可用一个P代器来实现对vector容器中所含元素的遍历?br /> 如下代码对vector容器对象生成和用了q代器:
2 vector<int>::iterator the_iterator;
3 for( int i=0; i < 10; i++ )
4 the_vector.push_back(i);
5 int total = 0;
6 the_iterator = the_vector.begin();
7 while( the_iterator != the_vector.end() )
8 {
9 total += *the_iterator;
10 the_iterator++;
11 }
12 cout << "Total=" << total << endl;
C++标准库ȝ
容器
序列
vector=========================<vector>
list===========================<list>
deque==========================<deque>
序列适配?br /> stack:top,push,pop=============<stack>
queue:front,back,push,pop======<queue>
priority_queue:top,push,pop====<queue>
兌容器
map============================<map>
multimap=======================<map>
set============================<set>
multiset=======================<set>
拟容?br /> string=========================<string>
valarray=======================<valarray>
bitset=========================<bitset>
法
http://www.cplusplus.com/reference/algorithm/ STL Algorithms 详细说明?br />
非修Ҏ序列操?br /><algorithm>
for_each()=====================对序列中每个元素执行操作
find()=========================在序列中找某个值的W一个出?br /> find_if()======================在序列中扄合某谓词的第一个元?br /> find_first_of()================在序列中扑֏一序列里的?br /> adjust_find()==================扑և盔R的一对?br /> count()========================在序列中l计某个值出现的ơ数
count_if()=====================在序列中l计与某谓词匚w的次?br /> mismatch()=====================找两序列相异的W一个元?br /> equal()========================如果两个序列对应元素都相同则为真
search()=======================扑և一序列作ؓ子序列的W一个出C|?br /> find_end()=====================扑և一序列作ؓ子序列的最后一个出C|?br /> search_n()=====================扑և一序列作ؓ子序列的Wn个出C|?br />修改性的序列操作
<algorithm>
transform()====================操作应用于序列中的每个元素
copy()=========================从序列的W一个元素vq行复制
copy_backward()================从序列的最后元素vq行复制
swap()=========================交换两个元素
iter_swap()====================交换pP代器所指的两个元素
swap_ranges()==================交换两个序列中的元素
replace()======================用一个给定值替换一些元?br /> replace_if()===================替换满谓词的一些元?br /> replace_copy()=================复制序列时用一个给定值替换元?br /> replace_copy_if()==============复制序列时替换满词的元素
fill()=========================用一个给定值取代所有元?br /> fill_n()=======================用一个给定值取代前n个元?br /> generate()=====================用一个操作的l果取代所有元?br /> generate_n()===================用一个操作的l果取代前n个元?br /> remove()=======================删除hl定值的元素
remove_if()====================删除满谓词的元?br /> remove_copy()==================复制序列时删除给定值的元素
remove_copy_if()===============复制序列时删除满词的元素
unique()=======================删除盔R的重复元?br /> unique_copy()==================复制序列时删除相ȝ重复元素
reexample()======================反{元素的次?br /> reexample_copy()=================复制序列时反转元素的ơ序
rotate()=======================循环Ud元素
rotate_copy()==================复制序列时@环移动元?br /> random_shuffle()===============采用均匀分布随机Ud元素
序列排序
<algorithm>
sort()=========================以很好的q_ơ序排序
stable_sort()==================排序且维持相同元素原有的序
partial_sort()=================序列的前一部分排好?br /> partial_sort_copy()============复制的同时将序列的前一部分排好?br /> nth_element()==================第n个元素放到它的正位|?br /> lower_bound()==================扑ֈ某个值的W一个出?br /> upper_bound()==================扑ֈ大于某个值的W一个出?br /> equal_range()==================扑ևhl定值的一个子序列
binary_search()================在排好序的序列中定l定元素是否存在
merge()========================归ƈ两个排好序的序列
inplace_merge()================归ƈ两个接箋的排好序的序?br /> partition()====================满x谓词的元素都攑ֈ前面
stable_partition()=============满x谓词的元素都攑ֈ前面且维持原序
集合法
<algorithm>
include()======================如果一个序列是另一个的子序列则为真
set_union()====================构造一个已排序的ƈ?br /> set_intersection()=============构造一个已排序的交?br /> set_difference()===============构造一个已排序序列Q包含在W一个序列但不在W二个序列的元素
set_symmetric_difference()=====构造一个已排序序列Q包括所有只在两个序列之一中的元素
堆操?br /><algorithm>
make_heap()====================序列高速得能够作ؓ堆?br /> push_heap()====================向堆中加入一个元?br /> pop_heap()=====================从堆中去除元?br /> sort_heap()====================对堆排序
最大和最?br /><algorithm>
min()==========================两个g较小?br /> max()==========================两个g较大?br /> min_element()==================序列中的最元?br /> max_element()==================序列中的最大元?br /> lexicographic_compare()========两个序列中按字典序的W一个在?br />排列
<algorithm>
next_permutation()=============按字典序的下一个排?br /> prev_permutation()=============按字典序的前一个排?br />通用数值算?br /><numeric>
accumulate()===================U篏在一个序列中q算的结?向量的元素求各的推广)
inner_product()================U篏在两个序列中q算的结?内积)
partial_sum()==================通过在序列上的运生序?增量变化)
adjacent_difference()==========通过在序列上的运生序?与partial_sum相反)
C风格法
<cstdlib>
qsort()========================快速排序,元素不能有用户定义的构造,拯赋值和析构函数
bsearch()======================二分法查找,元素不能有用户定义的构造,拯赋值和析构函数
函数对象
基类
template<class Arg, class Res> struct unary_function
template<class Arg, class Arg2, class Res> struct binary_function
谓词
q回bool的函数对象?br /><functional>
equal_to=======================二元Qarg1 == arg2
not_equal_to===================二元Qarg1 != arg2
greater========================二元Qarg1 > arg2
less===========================二元Qarg1 < arg2
greater_equal==================二元Qarg1 >= arg2
less_equal=====================二元Qarg1 <= arg2
logical_and====================二元Qarg1 && arg2
logical_or=====================二元Qarg1 || arg2
logical_not====================一元,!arg
术函数对象
<functional>
plus===========================二元Qarg1 + arg2
minus==========================二元Qarg1 - arg2
multiplies=====================二元Qarg1 * arg2
divides========================二元Qarg1 / arg2
modulus========================二元Qarg1 % arg2
negate=========================一元,-arg
U束器,适配器和否定?br /><functional>
bind2nd(y)
binder2nd==================以y作ؓW二个参数调用二元函?br /> bind1st(x)
binder1st==================以x作ؓW一个参数调用二元函?br /> mem_fun()
mem_fun_t==================通过指针调用0元成员函?br /> mem_fun1_t=================通过指针调用一元成员函?br /> const_mem_fun_t============通过指针调用0元const成员函数
const_mem_fun1_t===========通过指针调用一元const成员函数
mem_fun_ref()
mem_fun_ref_t==============通过引用调用0元成员函?br /> mem_fun1_ref_t=============通过引用调用一元成员函?br /> const_mem_fun_ref_t========通过引用调用0元const成员函数
const_mem_fun1_ref_t=======通过引用调用一元const成员函数
ptr_fun()
pointer_to_unary_function==调用一元函数指?br /> ptr_fun()
pointer_to_binary_function=调用二元函数指针
not1()
unary_negate===============否定一元谓?br /> not2()
binary_negate==============否定二元谓词
q代?br />分类
Output: *p= , ++
Input: =*p , -> , ++ , == , !=
Forward: *p= , =*p , -> , ++ , == , !=
Bidirectional: *p= , =*p -> , [] , ++ , -- , == , !=
Random: += , -= , *p= , =*p -> , [] , ++ , -- , + , - , == , != , < , > , <= , >=
插入?br /> template<class Cont> back_insert_iterator<Cont> back_inserter(Cont& c);
template<class Cont> front_insert_iterator<Cont> front_inserter(Cont& c);
template<class Cont, class Out> insert_iterator<Cont> back_inserter(Cont& c, Out p);
反向q代?br /> reexample_iterator===============rbegin(), rend()
P代器
ostream_iterator===============用于向ostream写入
istream_iterator===============用于向istreamd
ostreambuf_iterator============用于向流~冲区写?br /> istreambuf_iterator============用于向流~冲?br />
分配?/strong>
<memory>
template<class T> class std::allocator
数?/strong>
数值的限制
<limits>
numeric_limits<>
<climits>
CHAR_BIT
INT_MAX
...
<cfloat>
DBL_MIN_EXP
FLT_RADIX
LDBL_MAX
...
标准数学函数
<cmath>
double abs(double)=============l对?不在C?Q同fabs()
double fabs(double)============l对?br /> double ceil(double d)==========不小于d的最整?br /> double floor(double d)=========不大于d的最大整?br /> double sqrt(double d)==========d在^ҎQd必须非负
double pow(double d, double e)=d的eơ幂
double pow(double d, int i)====d的iơ幂
double cos(double)=============余u
double sin(double)=============正u
double tan(double)=============正切
double acos(double)============反余?br /> double asin(double)============反正?br /> double atan(double)============反正?br /> double atan2(double x,double y) //atan(x/y)
double sinh(double)============双曲正u
double cosh(double)============双曲余u
double tanh(double)============双曲正切
double exp(double)=============指数Q以e为底
double log(double d)===========自动Ҏ(以e为底),d必须大于0
double log10(double d)=========10底对敎ͼd必须大于0
double modf(double d,double*p)=q回d的小数部分,整数部分存入*p
double frexp(double d, int* p)=扑և[0.5,1)中的x,y,使d=x*pow(2,y),q回xq将y存入*p
double fmod(double d,double m)=点C敎ͼW号与d相同
double ldexp(double d, int i)==d*pow(2,i)
<cstdlib>
int abs(int)===================l对?br /> long abs(long)=================l对?不在C?
long labs(long)================l对?br /> struct div_t { implementation_defined quot, rem; }
struct ldiv_t { implementation_defined quot, rem; }
div_t div(int n, int d)========用d除nQ返?商,余数)
ldiv_t div(long n, long d)=====用d除nQ返?商,余数)(不在C?
ldiv_t ldiv(long n, long d)====用d除nQ返?商,余数)
向量术
<valarray>
valarray
复数术
<complex>
template<class T> class std::complex;
]]>
C++队列是一U容器适配器,它给予程序员一U先q先?FIFO)的数据结构?br />1.back() q回一个引用,指向最后一个元?br />2.empty() 如果队列I则q回?br />3.front() q回W一个元?br />4.pop() 删除W一个元?br />5.push() 在末֊入一个元?br />6.size() q回队列中元素的个数
队列可以用线性表(list)或双向队?deque)来实?注意vector container 不能用来实现queueQ因为vector 没有成员函数pop_front!)Q?br />queue<list<int>> q1;
queue<deque<int>> q2;
其成员函数有“判空(empty)” ?#8220;寸(Size)” ?#8220;首元(front)” ?#8220;օ(backt)” ?#8220;加入队列(push)” ?#8220;弹出队列(pop)”{操作?br />
例:
2 {
3 queue<int> q;
4 q.push(4);
5 q.push(5);
6 printf("%d\n",q.front());
7 q.pop();
8 }
C++ Priority Queues(优先队列)
C++优先队列cM队列Q但是在q个数据l构中的元素按照一定的断言排列有序?br />1.empty() 如果优先队列为空Q则q回?br />2.pop() 删除W一个元?br />3.push() 加入一个元?br />4.size() q回优先队列中拥有的元素的个?br />5.top() q回优先队列中有最高优先的元?br />
优先U队列可以用向量(vector)或双向队?deque)来实?注意list container 不能用来实现queueQ因为list 的P代器不是L存取iteratorQ而pop 中用到堆排序时是要求randomaccess iterator ?)Q?br />priority_queue<vector<int>, less<int>> pq1; // 使用递增less<int>函数对象排序
priority_queue<deque<int>, greater<int>> pq2; // 使用递减greater<int>函数对象排序
其成员函数有“判空(empty)” ?#8220;寸(Size)” ?#8220;栈顶元素(top)” ?#8220;压栈(push)” ?#8220;Ҏ(pop)”{?br />
例:
2 #include <queue>
3 using namespace std;
4
5 class T {
6 public:
7 int x, y, z;
8 T(int a, int b, int c):x(a), y(b), z(c)
9 {
10 }
11 };
12 bool operator < (const T &t1, const T &t2)
13 {
14 return t1.z < t2.z; // 按照z的顺序来军_t1和t2的顺?/span>
15 }
16 main()
17 {
18 priority_queue<T> q;
19 q.push(T(4,4,3));
20 q.push(T(2,2,5));
21 q.push(T(1,5,4));
22 q.push(T(3,3,6));
23 while (!q.empty())
24 {
25 T t = q.top();
26 q.pop();
27 cout << t.x << " " << t.y << " " << t.z << endl;
28 }
29 return 1;
30 }
3 3 6
2 2 5
1 5 4
4 4 3
再看一个按照z的顺序从到大出队的例子Q?
2 #include <queue>
3 using namespace std;
4 class T
5 {
6 public:
7 int x, y, z;
8 T(int a, int b, int c):x(a), y(b), z(c)
9 {
10 }
11 };
12 bool operator > (const T &t1, const T &t2)
13 {
14 return t1.z > t2.z;
15 }
16 main()
17 {
18 priority_queue<T, vector<T>, greater<T> > q;
19 q.push(T(4,4,3));
20 q.push(T(2,2,5));
21 q.push(T(1,5,4));
22 q.push(T(3,3,6));
23 while (!q.empty())
24 {
25 T t = q.top();
26 q.pop();
27 cout << t.x << " " << t.y << " " << t.z << endl;
28 }
29 return 1;
30 }
4 4 3
1 5 4
2 2 5
3 3 6
如果我们把第一个例子中的比较运符重蝲为: bool operator < (const T &t1, const T &t2) { return t1.z > t2.z; // 按照z的顺序来军_t1和t2的顺序} 则第一个例子的E序会得到和W二个例子的E序相同的输出结果?br />
]]>
2.pop() U除栈顶元素
3.push() 在栈增加元?br />4.size() q回栈中元素数目
5.top() q回栈顶元素
栈可以用向量(vector)、线性表(list)或双向队?deque)来实玎ͼ
stack<vector<int>> s1;
stack<list<int> > s2;
stack<deque<int>> s3;
其成员函数有“判空(empty)” ?#8220;寸(Size)” ?#8220;栈顶元素(top)” ?#8220;压栈(push)” ?#8220;Ҏ(pop)”{?br />
范例引自Q?a >http://blog.csdn.net/morewindows/article/details/6950881
2 {
3 //可以使用list或vector作ؓ栈的容器Q默认是使用deque的?nbsp;
4 stack<int, list<int>> a;
5 stack<int, vector<int>> b;
6 int i;
7
8 //压入数据
9 for (i = 0; i < 10; i++)
10 {
11 a.push(i);
12 b.push(i);
13 }
14
15 //栈的大小
16 printf("%d %d\n", a.size(), b.size());
17
18 //取栈Ҏ据ƈ数据弹出栈
19 while (!a.empty())
20 {
21 printf("%d ", a.top());
22 a.pop();
23 }
24 putchar('\n');
25
26 while (!b.empty())
27 {
28 printf("%d ", b.top());
29 b.pop();
30 }
31 putchar('\n');
32 return 0;
33 }
34
]]>
集合(Set)是一U包含已排序对象的关联容器。多元集?MultiSets)和集?Sets)相像Q只不过支持重复对象,其用法与set基本相同?br />Set 又称集合Q实际上是一l元素的集合Q但其中所包含的元素的值是唯一的,且是按一定顺序排列的Q集合中的每个元素被UC集合中的实例。因为其内部是通过链表的方式来l织Q所以在插入的时候比vector 快,但在查找和末添加上比vector 慢?br />multiset 是多重集合,其实现方式和set 是相似的Q只是它不要求集合中的元素是唯一的,也就是说集合中的同一个元素可以出现多ơ?br />
构造:
explicit set(const Compare&=compare());
如:set<int,less<int> > set1;
less<int>是一个标准类Q用于Ş成升序排列函数对象。降序排列是用greater<int>?
Template<class InputIterator> set(InputIterator, InputIterator,\ const Compare&=compare());
如:set<int ,less<int> >set2(vector1.begin(),vector1.end());
通过指定某一预先定义的区间来初始化set对象的构造函数?
setQconst set<Key,Compare&>Q?
如:set<int ,less<int> >set3(set2);
ҎQ?/strong>
1.begin() q回指向W一个元素的q代?br />2.clear() 清除所有元?br />3.count() q回某个值元素的个数
4.empty() 如果集合为空Q返回true
5.end() q回指向最后一个元素的q代?br />6.equal_range() q回W一?gt;=关键字的q代器和>关键字的q代?br /> 语法Q?br /> pair <iterator,iterator>equal_range( const key_type &key );
//key是用于排序的关键?br /> Set<int> ctr;
例如Q?br /> Pair<set<int>::iterator,set<int>::iterarot>p;
For(i=0;i<=5;i++) ctr.insert(i);
P=ctr.equal_range(2);
那么*p.first==2;*p.second==3;
7.erase() 删除集合中的元素
语法:
iterator erase( iterator i ); //删除i位置元素
iterator erase( iterator start, iterator end );
//删除从start开始到end(end为第一个不被删除的?l束的元?br /> size_type erase( const key_type &key );
//删除{于key值的所有元素(q回被删除的元素的个敎ͼ
//前两个返回第一个不被删除的双向定位?不存在返回末?br /> //W三个返回删除个?br />8.find() q回一个指向被查找到元素的q代?br /> 语法:
iterator find( const key_type &key );
//查找{于key值的元素Qƈq回指向该元素的q代?
//如果没有扑ֈ,q回指向集合最后一个元素的q代?br />9.get_allocator() q回集合的分配器
10.insert() 在集合中插入元素
语法:
iterator insert( iterator i, const TYPE &val ); //在P代器i前插入val
void insert( input_iterator start, input_iterator end );
//P代器start开始到endQend不被插入Q结束返回内的元素插入到集合?br /> pair insert( const TYPE &val );
//插入val元素Q返回指向该元素的P代器和一个布值来说明val是否成功被插?br /> //应该注意的是在集?Sets中不能插入两个相同的元素)
11.lower_bound() q回指向大于Q或{于Q某值的W一个元素的q代?br /> 语法:
iterator lower_bound( const key_type &key );
//q回一个指向大于或者等于key值的W一个元素的q代?br />12.key_comp() q回一个用于元素间值比较的函数
语法:
key_compare key_comp();
//q回一个用于元素间值比较的函数对象
13.max_size() q回集合能容U的元素的最大限?br />14.rbegin() q回指向集合中最后一个元素的反向q代?br /> CZQ?br /> Set<int> ctr;
Set<int>::reverse_iterator rcp;
For(rcp=ctr.rbegin();rcp!=ctr.rend();rcp++)
Cout<<*rcp<<” ”;
15.rend() q回指向集合中第一个元素的反向q代?br />16.size() 集合中元素的数目
17.swap() 交换两个集合变量
语法:
void swap( set &object ); //交换当前集合和object集合中的元素
18.upper_bound() q回大于某个值元素的q代?br /> 语法:
iterator upwer_bound( const key_type &key );
//q回一个指向大于key值的W一个元素的q代?br />19.value_comp() q回一个用于比较元素间的值的函数
语法:
iterator upper_bound( const key_type &key );//q回一个用于比较元素间的值的函数对象
20.Set集合的ƈQ交和差
set_union(a.begin(),a.end(),b.begin(),b.end(),insert_iterator<set<int> >(c,c.begin()));
set_intersection(a.begin(),a.end(),b.begin(),b.end(),insert_iterator<set<int> >(c,c.begin()));
set_difference(a.begin(),a.end(),b.begin(),b.end(),insert_iterator<set<int> >(c,c.begin()));
以下转自Q?a >http://blog.csdn.net/wangji163163/article/details/3740948
2 class Key,
3 class Traits=less<Key>,
4 class Allocator=allocator<Key>
5 >
6 class set?/span>
2 while(it!=s.end())
3 {
4 cout<<*it++<<endl;//q代器依ơ后U,直到末尾?/span>
5 }
2
3 while(it!=s.rend())
4
5 {cout<<*it++<<endl;}
2 class _InIt2,
3 class _OutIt> inline
4 _OutIt set_intersection(_InIt1 _First1, _InIt1 _Last1,
5 _InIt2 _First2, _InIt2 _Last2, _OutIt _Dest)
6 { // AND sets [_First1, _Last1) and [_First2, _Last2), using operator<
7 for (; _First1 != _Last1 && _First2 != _Last2; )
8 if (*_First1 < *_First2)
9 ++_First1;
10 else if (*_First2 < *_First1)
11 ++_First2;
12 else
13 *_Dest++ = *_First1++, ++_First2;
14 return (_Dest);
15 }
3 std::set_differenceQ)Q差?br /> 4
5 set_symmetric_differenceQ)Q得到的l果是第一个P代器相对于第二个的差集ƈ上第二个相当于第一个的差集。代码:
6
7 struct compare
8 {
9 bool operator ()(string s1,string s2)
10 {
11 return s1>s2;
12 }///自定义一个仿函数
13 };
14 int main()
15 {
16 typedef std::set<string,compare> _SET;
17 _SET s;
18 s.insert(string("sfdsfd"));
19 s.insert(string("apple"));
20 s.insert(string("english"));
21 s.insert(string("dstd"));
22 cout<<"s1:"<<endl;
23 std::set<string,compare>::iterator it = s.begin();
24 while(it!=s.end())
25 cout<<*it++<<" ";
26 cout<<endl<<"s2:"<<endl;
27 _SET s2;
28 s2.insert(string("abc"));
29 s2.insert(string("apple"));
30 s2.insert(string("english"));
31 it = s2.begin();
32 while(it!=s2.end())
33 cout<<*it++<<" ";
34 cout<<endl<<endl;
35
36 string str[10];
37 string *end = set_intersection(s.begin(),s.end(),s2.begin(),s2.end(),str,compare());//求交集,q回值指向str最后一个元素的
38 cout<<"result of set_intersection s1,s2:"<<endl;
39 string *first = str;
40 while(first<end)
41 cout <<*first++<<" ";
42 cout<<endl<<endl<<"result of set_union of s1,s2"<<endl;
43 end = std::set_union(s.begin(),s.end(),s2.begin(),s2.end(),str,compare());//q
44 first = str;
45 while(first<end)
46 cout <<*first++<<" ";
47 cout<<endl<<endl<<"result of set_difference of s2 relative to s1"<<endl;
48 first = str;
49 end = std::set_difference(s.begin(),s.end(),s2.begin(),s2.end(),str,compare());//s2相对于s1的差?/span>
50 while(first<end)
51 cout <<*first++<<" ";
52 cout<<endl<<endl<<"result of set_difference of s1 relative to s2"<<endl;
53 first = str;
54 end = std::set_difference(s2.begin(),s2.end(),s.begin(),s.end(),str,compare());//s1相对于s2的差?/span>
55
56 while(first<end)
57 cout <<*first++<<" ";
58 cout<<endl<<endl;
59 first = str;
60 end = std::set_symmetric_difference(s.begin(),s.end(),s2.begin(),s2.end(),str,compare());//上面两个差集的ƈ?/span>
61 while(first<end)
62 cout <<*first++<<" ";
63 cout<<endl;
64 }
65
66 set<int> s3 ;
67 set<int>::iterator iter = s3.begin() ;
68 set_intersection(s1.begin(),s1.end(),s2.begin(),s2.end(),inserter(s3,iter));
69 copy(s3.begin(),s3.end(), ostream_iterator<int>(cout," "));
]]>
]]>
是一U优化了的、对序列两端元素q行d和删除操作的基本序列容器。它允许较ؓ快速地随机讉KQ但它不?/span>vector 把所有的对象保存在一块连l的内存块,而是采用多个q箋的存储块Qƈ且在一个映结构中保存对这些块及其序的跟t。向deque 两端d或删除元素的开销很小。它不需要重新分配空_所以向末端增加元素?/span>vector 更有效?
实际上,deque 是对vector ?/span>list 优缺点的l合Q它是处于两者之间的一U容器?
Deque 的特点:
(1) 随机讉K方便Q即支持[ ] 操作W和vector.at() Q但性能没有vector 好;
(2) 可以在内部进行插入和删除操作Q但性能不及list Q?
(3) 可以在两端进?/span>push ?/span>pop Q?
(4) 相对?/span>verctor 占用更多的内存?
双向队列和向量很怼Q但是它允许在容器头部快速插入和删除Q就像在N一P?/span>
1.Constructors 创徏一个新双向队列
语法:
deque();//创徏一个空双向队列
deque( size_type size );// 创徏一个大ؓsize的双向队?
deque( size_type num, const TYPE &val ); //攄num?/span>val的拷贝到队列?
deque( const deque &from );// ?/span>from创徏一个内容一L双向队列
deque( input_iterator start, input_iterator end );
// start ?end - 创徏一个队列,保存?/span>start?/span>end的元素?
2.Operators 比较和赋值双向队?
//可以使用[]操作W访问双向队列中单个的元?
3.assign() 讄双向队列的?
语法:
void assign( input_iterator start, input_iterator end);
//start?/span>end指示的范围ؓ双向队列赋?
void assign( Size num, const TYPE &val );//讄?/span>num?/span>val?
4.at() q回指定的元?nbsp;
语法:
reference at( size_type pos ); q回一个引用,指向双向队列中位|?/span>pos上的元素
5.back() q回最后一个元?
语法:
reference back();//q回一个引用,指向双向队列中最后一个元?
6.begin() q回指向W一个元素的q代?
语法:
iterator begin();//q回一个P代器Q指向双向队列的W一个元?
7.clear() 删除所有元?
8.empty() q回真如果双向队列ؓI?
9.end() q回指向N的P代器
10.erase() 删除一个元?
语法:
iterator erase( iterator pos ); //删除pos位置上的元素
iterator erase( iterator start, iterator end ); //删除start?/span>end之间的所有元?
//q回指向被删除元素的后一个元?
11.front() q回W一个元素的引用
12.get_allocator() q回双向队列的配|器
13.insert() 插入一个元素到双向队列?
语法:
iterator insert( iterator pos, size_type num, const TYPE &val ); //pos前插?/span>num?/span>val?
void insert( iterator pos, input_iterator start, input_iterator end );
//插入?/span>start?/span>end范围内的元素?/span>pos前面
14.max_size() q回双向队列能容U的最大元素个?
15.pop_back() 删除N的元?
16.pop_front() 删除头部的元?
17.push_back() 在尾部加入一个元?
18.push_front() 在头部加入一个元?
19.rbegin() q回指向N的逆向q代?
20.rend() q回指向头部的逆向q代?
21.resize() 改变双向队列的大?
22.size() q回双向队列中元素的个数
23.swap() 和另一个双向队列交换元?
语法Q?
void swap( deque &target );// 交换target和现双向队列中元?/span>
C++ VectorQ向量容器)
是一个线性顺序结构。相当于数组Q但其大可以不预先指定Qƈ且自动扩展。它可以像数l一栯操作Q由于它的特性我们完全可以将vector 看作动态数l?
在创Z?/span>vector 后,它会自动在内存中分配一块连l的内存I间q行数据存储Q初始的I间大小可以预先指定也可以由vector 默认指定Q这个大即capacity Q)函数的返回倹{当存储的数据超q分配的I间时vector 会重新分配一块内存块Q但q样的分配是很耗时的,在重新分配空间时它会做这L动作Q?
首先Qvector 会申请一块更大的内存块;
然后Q将原来的数据拷贝到新的内存块中Q?
其次Q销毁掉原内存块中的对象Q调用对象的析构函数Q;
最后,原来的内存I间释放掉?
如果vector 保存的数据量很大Ӟq样的操作一定会Dp糕的性能Q这也是vector 被设计成比较Ҏ拯的值类型的原因Q。所以说vector 不是在什么情况下性能都好Q只有在预先知道它大的情况下vector 的性能才是最优的?/span>
vector 的特点:
(1) 指定一块如同数l一Lq箋存储Q但I间可以动态扩展。即它可以像数组一h作,q且可以q行动态操作。通常体现?/span>push_back() pop_back() ?
(2) 随机讉K方便Q它像数l一栯讉KQ即支持[ ] 操作W和vector.at()
(3) 节省I间Q因为它是连l存储,在存储数据的区域都是没有被浪费的Q但是要明确一?/span>vector 大多情况下ƈ不是满存的,在未存储的区域实际是费的?
(4) 在内部进行插入、删除操作效率非怽Q这L操作基本上是被禁止的?/span>Vector 被设计成只能在后端进行追加和删除操作Q其原因?/span>vector 内部的实现是按照序表的原理?
(5) 只能?/span>vector 的最后进?/span>push ?/span>pop Q不能在vector 的头q行push ?/span>pop ?
(6) 当动态添加的数据过vector 默认分配的大时要进行内存的重新分配、拷贝与释放Q这个操作非常消耗性能?所以要vector 辑ֈ最优的性能Q最好在创徏vector 时就指定其空间大?
Vectors 包含着一pdq箋存储的元?/span>,其行为和数组cM。访?/span>Vector中的L元素或从末尾d元素都可以在帔RU时间复杂度内完成,而查扄定值的元素所处的位置或是?/span>Vector中插入元素则是线性时间复杂度?/span>
1.Constructors 构造函?
vector<int> v1; //构造一个空的vector
vector<int> v1( 5, 42 ); //构造了一个包?个gؓ42的元素的Vector
2.Operators 对vectorq行赋值或比较
C++ Vectors能够使用标准q算W? ==, !=, <=, >=, <, ?>.
要访问vector中的某特定位|的元素可以使用 [] 操作W?
两个vectors被认为是相等?如果:
1.它们h相同的容?
2.所有相同位|的元素相等.
vectors之间大小的比较是按照词典规则.
3.assign() 对Vector中的元素赋?
语法Q?
void assign( input_iterator start, input_iterator end );
// 区间[start, end)的元素赋到当前vector
void assign( size_type num, const TYPE &val );
// 赋num个gؓval的元素到vector?q个函数会清除掉ؓvector赋g前的内容?/span>
4.at() q回指定位置的元?
语法Q?
TYPE at( size_type loc );//差不多等同v[i];但比v[i]安全;
5.back() q回最末一个元?
6.begin() q回W一个元素的q代?
7.capacity() q回vector所能容U的元素数量(在不重新分配内存的情况下Q?
8.clear() 清空所有元?
9.empty() 判断Vector是否为空Q返回true时ؓI)
10.end() q回最末元素的q代?译注:实指向最末元素的下一个位|?
11.erase() 删除指定元素
语法Q?
iterator erase( iterator loc );//删除loc处的元素
iterator erase( iterator start, iterator end );//删除start和end之间的元?/span>
12.front() q回W一个元素的引用
13.get_allocator() q回vector的内存分配器
14.insert() 插入元素到Vector?
语法Q?
iterator insert( iterator loc, const TYPE &val );
//在指定位|loc前插入gؓval的元?q回指向q个元素的P代器,
void insert( iterator loc, size_type num, const TYPE &val );
//在指定位|loc前插入num个gؓval的元?
void insert( iterator loc, input_iterator start, input_iterator end );
//在指定位|loc前插入区间[start, end)的所有元?
15.max_size() q回Vector所能容U_素的最大数量(上限Q?
16.pop_back() U除最后一个元?
17.push_back() 在Vector最后添加一个元?
18.rbegin() q回VectorN的逆P代器
19.rend() q回Vector起始的逆P代器
20.reserve() 讄Vector最的元素容纳数量
//为当前vector预留臛_共容Usize个元素的I间
21.resize() 改变Vector元素数量的大?
语法:
void resize( size_type size, TYPE val );
//改变当前vector的大ؓsize,且对新创建的元素赋值val
22.size() q回Vector元素数量的大?
23.swap() 交换两个Vector
语法Q?
void swap( vector &from );
Vector用法 Q?/span>
1.声明Q?
一个vectorcM于一个动态的一l数l?/span>
vector<int> a; //声明一个元素ؓintcd的vector a
vectot<MyType> a; //声明一个元素ؓMyTypecd的vector a
q里的声明的a包含0个元素,既a.size()的gؓ0Q但它是动态的Q其大小会随着数据的插入和删除改变而改变?/span>
vector<int> a(100, 0); //q里声明的是一个已l存放了100?的整数vector
你可以用以下的几U方法声明一?vector 对象Q?/span>
vector<float> v(5, 3.25); //初始化有5 个元素,其值都?.25
vector<float> v_new1(v);
vector<float> v_new2 = v;
vector<float> v_new3(v.begin(), v.end());
q四个vector 对象是相{的Q可以用operator==来判断?/span>
2.向量操作
常用函数Q?
size_t size(); // q回vector的大,卛_含的元素个数
void pop_back(); // 删除vector末尾的元素,vector大小相应减一
void push_back(); //用于在vector的末添加元?
T back(); // q回vector末尾的元?
void clear(); // vector清空Qvector大小变ؓ0
其他讉K方式Q?
cout<<a[5]<<endl;
cout<<a.at(5)<<endl;
以上区别在于后者在讉K界时会抛出异常Q而前者不会?/span>
3.遍历
(1). for(vector<datatype>::iterator it=a.begin(); it!=a.end();it++)
cout<<*it<<endl;
(2). for(int i=0;i<a.size;i++)
cout<<a[i]<<endl;
现在惛_到容器中能保存的最大元素数量就可以?vector cȝ成员函数max_size()Q?/span>
vector<shape>::size_type max_size = my_shapes.max_size();
当前容器的实际尺?--- 已有的元素个数用size()Q?/span>
vector<shape>::size_type size = my_shapes.size();
像size_type 描述了vector 寸的类型,value_type 说明了其中保存的对象的类型:
cout << “value type: “ << typeid(vector<float>::value_type).name();
输出Q?/span>
value type: float
可以用capacity()来取得vector 中已分配内存的元素个敎ͼ
vector<int> v;
vector<int>::size_type capacity = v.capacity();
vector cM于数l,可以使用下标[]讉KQ?/span>
vector<int> v(10);
v[0] = 101;
注意到这里预先给10 个元素分配了I间。你也可以用vector 提供的插入函数来动态的?/span>
展容器。成员函数push_back()在vector 的尾部添加了一个元素:
v.push_back(3);
也可以用insert()函数完成同样的工作:
v.insert(v.end(), 3);
q里insert()成员函数需要两个参敎ͼ一个指向容器中指定位置的P代器(iterator)Q一个待?/span>
入的元素。insert()元素插入到q代器指定元素之前?/span>
现在对P代器(Iterator)做点解释。Iterator 是指?pointer)的泛化,iterator 要求定义
operator*Q它q回指定cd的倹{Iterator 常常和容器联pd一赗例子:
vector<int> v(3);
v[0] = 5;
v[1] = 2;
v[2] = 7;
vector<int>::iterator first = v.begin();
vector<int>::iterator last = v.end();
while (first != last)
cout << *first++ << “ “;
上面代码的输出是Q?/span>
5 2 7
begin()q回的是vector 中第一个元素的iteratorQ而end()q回的ƈ不是最后一个元素的
iteratorQ而是past the last element。在STL 中叫past-the-end iterator?br />
l合查找
vector<int>::iterator result = find( v.begin( ), v.end( ), 2 ); //查找2
if ( result == v.end( ) ) //没找?/span>
cout << "No" << endl;
else //扑ֈ
cout << "Yes" << endl;