set
简介
集合(Set)容器是一个按特定顺序存储唯一元素的关联容器。
类模板
1
2
3
4
template < class T ,
class Compare = less < T > ,
class Alloc = allocator < T > >
> class set ;
模板参数
1.
T:元素的类型。
2.
Compare:一个二元谓词,以两个元素为参数返回一个 bool 值。(比较函数)
3.
Alloc:容器内部用来管理内存分配及释放的内存分配器的类型。这个参数是可选的,它的默认值是 std::allocator.
详细说明
在一个集合中,元素的值同时可以用来标志对应的元素(即值是自身的主键),每个值必须是唯一的。主键是不可修改的,因此在 set 中的元素不能被逐个修改(所有元素保持恒定),但是可以删除某个元素或插入新的元素。
set 容器中的所有元素都是按由类型为 Compare 的比较对象指定的严格弱序规则排序的。
在用主键访问单个元素时,set 容器通常比 unordered_set 容器低效,但 set 容器允许按顺序直接对某个子集进行迭代。
set 容器通常被实现为一个二叉搜索树(及其变型),该数据结构具有对数据自动排序的功能。
支持双向迭代
相关函数使用说明
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#include <iostream>
#include <set>
#include <unordered_set>
using namespace std ;
struct Node {
int val ;
int id ;
Node ( int id , int val )
: val ( val ), id ( id ){
}
};
bool operator < ( const Node & a , const Node & b )
{
return a . val < b . val ;
}
int main ( int argc , const char * argv []) {
cout << "初始化一个set" << endl ;
set < int > test_set = { 2 , 3 , 19 , 8 , 6 , 7 };
cout << "删除一个元素" << endl ;
test_set . erase ( 19 );
cout << "遍历set里面的元素" << endl ;
for ( auto pos = test_set . begin (); pos != test_set . end (); pos ++ ) {
cout <<* pos << " " ;
}
cout << endl ;
cout << "查找元素的个数,如果为1就是找到,为0就是找不到" << endl ;
if ( test_set . count ( 5 ) == 1 ) {
cout << "have find" << endl ;
} else {
cout << "no find" << endl ;
}
cout << "查找元素的迭代器,找不到则返回最后一个元素的迭代器,找得到就返回元素的迭代器" << endl ;
if ( test_set . find ( 5 ) != test_set . end ()) {
cout << "have find" << endl ;
} else {
cout << "no find" << endl ;
}
cout << "有效元素个数" << endl ;
cout << test_set . size () << endl ;
cout << "自定义类型的set,默认是less函数(<),所以必须重载<操作符,其他用法跟标准的set一样" << endl ;
Node n1 ( 1 , 5 );
Node n2 ( 2 , 3 );
Node n3 ( 3 , 9 );
set < Node > node_set ;
node_set . insert ( n1 );
node_set . insert ( n2 );
node_set . insert ( n3 );
cout << "遍历自定义类型set里面的元素" << endl ;
for ( auto pos = node_set . begin (); pos != node_set . end (); pos ++ ) {
cout << pos -> id << " " ;
}
cout << endl ;
return 0 ;
}
unordered_set
简介
无序集合(Unordered Set)容器是一个存储唯一元素的关联容器,容器中的元素无特别的次序关系。该容器允许基于值地快速元素检索。
类模板
1
2
3
4
5
6
// <unordered_set>
template < class Key ,
class Hash = hash < Key > ,
class Pred = equal_to < Key > ,
class Alloc = allocator < Key >
> class unordered_set ;
模板参数
1.
Key:元素的类型。
2.
Hash:一元谓词,以一个 Key 类型的对象为参数,返回一个基于该对象的 size_t 类型的唯一值(哈希函数)。
3.
Pred:二元谓词,以两个 Key 类型的对象为参数,返回一个 bool 值,如果第一个参数等价于第二个参数,该 bool 值为 true,否则为 false。默认为 std::equal_to。
4.
Alloc:容器内部用来管理内存分配及释放的内存分配器的类型。这个参数是可选的,它的默认值是 std::allocator。
详细说明
在一个 unordered_set 容器中,元素的值同时可以用来标志对应的元素(即值是自身的主键),每个值必须是唯一的。主键是不可修改的,因此在 unordered_set 中的元素不能被逐个修改(所有元素保持恒定),但是可以删除某个元素或插入新的元素。
在 unordered_set 内部,元素不会按任何顺序排序,而是通过元素值的 hash 值将元素分组放置到各个槽(Bucket,也可译成“桶”)中,这样就能通过元素值快速地访问各个对应的元素(平均耗时为一个常量,即时间复杂度为 O(1))。
在访问容器中的某个元素时,unordered_set 容器比 set 容器高效,而在迭代容器元素的某个子集时,前者比后者稍微低效了一点。
unordered_set 容器支持正向迭代
相关函数说明
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include <iostream>
#include <set>
#include <unordered_set>
using namespace std ;
struct Node {
int val ;
int id ;
Node ( int id , int val )
: val ( val ), id ( id ){
}
};
struct node_hash_fun {
size_t operator ()( const Node & n ) const {
return n . id * 50 + n . val ;
}
};
struct node_equal_fun {
bool operator ()( const Node & n , const Node & m ) const {
return n . id == m . id && n . val == m . val ? true : false ;
}
};
int main ( int argc , const char * argv []) {
cout << "相当于java的hashSet,里面存放的元素是无序的,其他用法跟set大同小异" << endl ;
unordered_set < int > test_unordered_set = { 2 , 5 , 3 , 6 , 7 , 1 , 9 , 0 };
cout << "遍历unordered_set" << endl ;
for ( auto pos = test_unordered_set . begin (); pos != test_unordered_set . end (); pos ++ ) {
cout <<* pos << " " ;
}
cout << endl ;
Node n1 ( 1 , 5 );
Node n2 ( 2 , 3 );
Node n3 ( 3 , 9 );
cout << "自定义类型unordered_set,必须重载hash_func和==操作符,其他用法跟标准的unordered_set一样" << endl ; unordered_set < Node , node_hash_fun , node_equal_fun , allocator < Node >> node_unordered_set ;
node_unordered_set . insert ( n1 );
node_unordered_set . insert ( n2 );
node_unordered_set . insert ( n3 );
cout << "遍历自定义类型unordered_set" << endl ;
for ( auto pos = node_unordered_set . begin (); pos != node_unordered_set . end (); pos ++ ) {
cout << ( * pos ). id << " " ;
}
cout << endl ;
return 0 ;
}