C++:10.map、函数对象、一元、二元谓词

1. map

map 不能存 key 重复的数据,要么不生效,要么覆盖

map 会对 key 排序,二叉数算法

1.1. 添加数据:

  • map1.insert(pair<int,string>(01,"01")); // 重复添加不会覆盖值
  • map1.insert(make_pair(02,"02")); // 重复添加不会覆盖值
  • map1.insert(map<int,string>::value_type(03,"03")); // 重复添加不会覆盖值
  • map1[04] = "04" // 重复添加会覆盖
1
2
3
4
5
6
7
8
9
10
11
12
13
map<int,string> map1;

map1.insert(pair<int,string>(01,"01"));
map1.insert(make_pair(02,"02"));
map1.insert(map<int,string>::value_type(03,"03"));

//区别,如果用前面三种 key 重复添加,不生效
// map1.insert(map<int,string>::value_type(03,"30"));// 无效

// 第四种方式 = map[key] = value
map1[04] = "04";
// 这种方式会覆盖
map1[04] = "40";

1.2.判断是否添加成功:

1
2
3
4
5
6
pair<map<int,string>::iterator,bool> p = map1.insert(make_pair(06,"06"));
if(p.second){
cout << "添加成功" << endl;
}else{
cout << "添加失败" << endl;
}

1.3.循环:

1
2
3
4
// 循环迭代器
for(map<int,string>::iterator it = map1.begin(); it != map1.end(); it++){
cout << it->first << " - " << it->second.c_str() << endl;
}

1.4.删除:

auto:可以推到出类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
int main()
{
std::map<int, std::string> c = {{1, "one"}, {2, "two"}, {3, "three"},
{4, "four"}, {5, "five"}, {6, "six"}};

// erase all odd numbers from c
for(auto it = c.begin(); it != c.end(); ) {
if(it->first % 2 == 1)
it = c.erase(it);
else
++it;
}

for(auto& p : c) {
std::cout << p.second << ' ';
}
}

1.5查找:

1
2
3
4
5
6
7
8
map<int,string>::iterator find_it = map1.find(0); // 0指的是key

// cout << find_it->first << " - " << find_it->second.c_str() << endl;
if(find_it!=map1.end()){
cout << find_it->first << " - " << find_it->second.c_str() << endl;
}else{
cout << " 找不到 " << endl;
}

2. multimap

multimap 可存 key 重复的数据, 基本操作与 map 类似
multimap 是没有排序的

遍历和分组查询:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 遍历
for(auto it = map1.begin(); it != map1.end(); it++){
cout << it->first << " - " << it->second.c_str() << endl;
}
cout << " 遍历结束 " << endl;

// 分组查询 多个数据
multimap<int,string>::iterator find_it = map1.find(3);
while(find_it!=map1.end()){
cout << find_it->first << " - " << find_it->second.c_str() << endl;
find_it ++;
// 不是我们要找的内容
if(find_it == map1.end() || find_it -> first != 3){
cout << "到底了" <<endl;
break;
}
}

3. 容器存对象

javac++ 的区别:
java: java 中把对象添加到了集合,这个对象发送了改变,集合中的对象也会发生改变,他们是同一块地址
c++:中会调用对象的拷贝构造函数,存进去的是另一个对象

c++ 中容器中存对象需要注意的点:

  1. 没有默认的构造函数
  2. 析构函数也可能回调多次,如果说在析构函数中释放内存,需要在拷贝构造函数中进行深拷贝
1
2
3
4
5
6
7
8
9
10
11
12
13
14
int main(){
vector<Person> vector1;

Person person("eastrise");

// 会调用对象的拷贝构造函数,存进去的是另一个对象
vector1.push_back(person);

person.setName("Jack");

Person p1 = vector1.back();

cout << p1.name.c_str() << endl;
}

4. 函数对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Compare{
// 重载了括号操作符
public:
void operator()(){
cout << "仿函数" << endl;
}
};

void compare1(){
cout << "普通函数" << endl;
}

// 4. 函数对象(仿函数) 一元谓词,二元谓词
int main(){
Compare compare;

// 跟函数非常类似
compare();
// 普通函数调用
compare1();
}

5. 一元谓词

定义:重载(),并且需要传递1个参数,常返回int值用于计数

  • printObj = for_each(set1.begin(),set1.end(),printObj);:最后一个参数传一元函数对象
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
void print(int number){
cout << number << endl;
}

// 仿函数 - 一元谓词(能够记录状态)
class PrintObj{
public:
int count = 0;
void operator()(int number){
cout << number << endl;
count ++;
}
};

// 回调函数和仿函数的区别
int main(){
set<int> set1;

set1.insert(1);
set1.insert(2);
set1.insert(3);
set1.insert(4);

// for_each 迭代器,非常重要的一点就是:仿函数如果要保存记录状态,要确保对象一致,可以用返回值
// for_each(set1.begin(),set1.end(),print);
PrintObj printObj;
// 如果不用返回值,那么printObj 和
printObj = for_each(set1.begin(),set1.end(),printObj);
cout << "个数:" << printObj.count << endl;
}

6. 二元谓词

定义:重载(),并且需要传递2个参数,常返回bool值用于算法判断条件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class CompareObj{
public:
int count = 0;
bool operator()(const string str1,const string str2){
return str1 < str2;
}
};

int main(){
// 二元谓词的仿函数
set<string,CompareObj> set1;
set1.insert("aaa");
set1.insert("aAa");
set1.insert("ccc");
set1.insert("ddd");
// 是否包含 aaa , 遍历比较 , 找方法
for(set<string>::iterator it = set1.begin();it != set1.end(); it ++){
cout << (*it).c_str() << endl;
}
}
-------------本文结束感谢您的阅读-------------
坚持原创技术分享,您的支持将鼓励我继续创作!
0%