文章目录
一. 常用算法概述
二. 常用的遍历算法
① for_each 遍历容器
原型:
/*----------------------------------------------------------------
* 项目: Classical Question
* 作者: Fioman
* 邮箱: geym@hengdingzhineng.com
* 时间: 2022/3/22
* 格言: Talk is cheap,show me the code ^_^
//----------------------------------------------------------------*/
#include <iostream>
using namespace std;
#include<vector>
#include<algorithm>
void print_01(int val)
{
cout << val << " ";
}
class Print_02
{
public:
void operator()(int val)
{
cout << val << " ";
}
};
void test_01(void)
{
vector<int> v;
for (int i = 0; i < 10; i++)
{
v.push_back(i);
}
// 使用for_each遍历
for_each(v.begin(), v.end(),print_01);
cout << endl;
// 使用仿函数,注意仿函数使用的时候比普通的函数多个括号
// 这里为啥多个括号,其实Print_02本身不是哥函数,Print_02()这里会返回
// operator()这个函数
for_each(v.begin(), v.end(), Print_02());
cout << endl;
}
int main()
{
test_01();
system("pause");
return 0;
}
② transform 搬运容器到另外一个容器中,并且搬运的过程中可以通过普通函数或者仿函数进行操作
函数原型:
beg1
源容器开始迭代器
end1
源容器结束迭代器
beg2
目标容器开始迭代器
_func
普通的函数或者是函数对象(仿函数)
注意:
/*----------------------------------------------------------------
* 项目: Classical Question
* 作者: Fioman
* 邮箱: geym@hengdingzhineng.com
* 时间: 2022/3/22
* 格言: Talk is cheap,show me the code ^_^
//----------------------------------------------------------------*/
#include <iostream>
using namespace std;
#include<vector>
#include<algorithm>
class Transform
{
public:
int operator()(int val)
{
return val;
}
};
void my_print(int val)
{
cout << val << " ";
}
// 常用遍历算法 transform
void test_01(void)
{
vector<int> v;
for (int i = 0; i < 10; i++)
{
v.push_back(i);
}
vector<int> vTarget; // 目标容器
vTarget.resize(v.size()); // 这一步一定要有,不然容易报错
// 开始搬运
transform(v.begin(), v.end(), vTarget.begin(), Transform());
// 遍历
for_each(vTarget.begin(), vTarget.end(), my_print);
cout << endl;
}
int main()
{
test_01();
system("pause");
return 0;
}
三. 常用的查找算法
① find
原型:
- 按值查找元素,找到了返回指定位置迭代器,找不到返回结束位置迭代器
beg
开始迭代器end
结束迭代器value
查找的元素
/*----------------------------------------------------------------
* 项目: Classical Question
* 作者: Fioman
* 邮箱: geym@hengdingzhineng.com
* 时间: 2022/3/22
* 格言: Talk is cheap,show me the code ^_^
//----------------------------------------------------------------*/
#include <iostream>
using namespace std;
#include<algorithm>
#include<vector>
#include<string>
class Person
{
public:
Person(string name, int age)
{
this->mName = name;
this->mAge = age;
}
// 重载 == 运算符,find函数在查找的时候会自动调用
bool operator==(const Person p)
{
return this->mName == p.mName && this->mAge == p.mAge;
}
string mName;
int mAge;
};
void test_01(void)
{
vector<int> v;
for (int i = 0; i < 10; i++)
{
v.push_back(i);
}
// 查找,容器中是否有5这个元素
vector<int>::iterator it = find(v.begin(),v.end(),5);
if (it != v.end())
{
cout << "成功找到了 " << *it << endl;
}
else
{
cout << "未找到!" << endl;
}
// 查找自定义的数据类型的时候,自定义的数据类型,要重载==比较运算符
// 因为find查找的时候,就是去调用这个运算符函数去对比的
Person p1("A", 10);
Person p2("B", 20);
Person p3("C", 30);
vector<Person> v2;
v2.push_back(p1);
v2.push_back(p2);
v2.push_back(p3);
vector<Person>::iterator it2 = find(v2.begin(), v2.end(), p2);
if (it2 == v2.end())
{
cout << "未找到 p2" << endl;
}
else
{
cout << "找到了p2: " << " 姓名: " << it2->mName << " 年龄: " << it2->mAge << endl;
}
}
int main()
{
test_01();
system("pause");
return 0;
}
结果:
② find_if
函数原型
- 按值进行查找元素,找到了返回指定位置的迭代器,找不到返回结束迭代器位置
- begin 开始迭代器
- end 结束迭代器位置
- _Pred 函数或者谓词(返回bool类型的仿函数)
/*----------------------------------------------------------------
* 项目: Classical Question
* 作者: Fioman
* 邮箱: geym@hengdingzhineng.com
* 时间: 2022/3/22
* 格言: Talk is cheap,show me the code ^_^
//----------------------------------------------------------------*/
#include <iostream>
using namespace std;
#include<algorithm>
#include<vector>
#include<string>
// 创建一元谓词
class GreaterFive
{
public:
bool operator()(int val)
{
return val > 5;
}
};
// 1.查找内置的数据类型
void test_01(void)
{
vector<int> v;
for (int i = 0; i < 10; i++)
{
v.push_back(i);
}
vector<int>::iterator it = find_if(v.begin(), v.end(), GreaterFive());
if (it != v.end())
{
cout << "找到了大于5的数,值为: " << *it << endl;
}
else
{
cout << "未找到大于5的数" << endl;
}
}
// 查找自定义的数据类型
class Person
{
public:
Person(string name, int age)
{
this->mName = name;
this->mAge = age;
}
string mName;
int mAge;
};
class Greater20
{
public:
bool operator()(const Person p)
{
return p.mAge > 20;
}
};
void test_02(void)
{
Person p1("A", 10);
Person p2("B", 20);
Person p3("C", 30);
Person p4("D", 40);
Person p5("E", 50);
Person p6("F", 60);
vector<Person> v;
v.push_back(p1);
v.push_back(p2);
v.push_back(p3);
v.push_back(p4);
v.push_back(p5);
v.push_back(p6);
vector<Person>::iterator it = find_if(v.begin(), v.end(), Greater20());
if (it != v.end())
{
cout << "查找成功: " << "姓名: " << it->mName << " 年龄: " << it->mAge << endl;
}
else
{
cout << "查找失败!" << endl;
}
}
int main()
{
test_01();
test_02();
system("pause");
return 0;
}
结果:
③ adjacent_find
原型:
- 查找相邻重复元素,返回相邻重复元素的第一个位置的迭代器,如果没有返回end();
- begin: 开始迭代器
- end: 结束迭代器
- 可以用这个算法来删除重复元素,如果找到了重复元素就通过
erase
删除
/*----------------------------------------------------------------
* 项目: Classical Question
* 作者: Fioman
* 邮箱: geym@hengdingzhineng.com
* 时间: 2022/3/22
* 格言: Talk is cheap,show me the code ^_^
//----------------------------------------------------------------*/
#include <iostream>
using namespace std;
#include <algorithm>
#include<vector>
void print_vector(const vector<int> &v)
{
for (vector<int>::const_iterator it = v.begin(); it != v.end(); it++)
{
cout << *it << " ";
}
cout << endl;
}
void test_01(void)
{
vector<int> v;
v.push_back(2);
v.push_back(2);
v.push_back(0);
v.push_back(0);
v.push_back(1);
v.push_back(1);
v.push_back(3);
v.push_back(3);
// 查找相邻的重复元素,然后删除
vector<int>::iterator it = adjacent_find(v.begin(), v.end());
while (it != v.end())
{
cout << "找到了重复元素: " << *it << endl;
v.erase(it);
it = adjacent_find(v.begin(), v.end());
}
cout << "重复元素删除之后的结果: " << endl;
print_vector(v);
}
int main()
{
test_01();
system("pause");
return 0;
}
结果:
④ binary_search
原型:
- 查找指定的元素,查找到返回true,否则返回false
- 注意: 在无序序列中不可用
- begin: 开始迭代器
- end: 结束迭代器
- value: 查找的元素
/*----------------------------------------------------------------
* 项目: Classical Question
* 作者: Fioman
* 邮箱: geym@hengdingzhineng.com
* 时间: 2022/3/22
* 格言: Talk is cheap,show me the code ^_^
//----------------------------------------------------------------*/
#include <iostream>
using namespace std;
#include<algorithm>
#include<vector>
void test_01(void)
{
vector<int> v;
for (int i = 0; i < 10; i++)
{
v.push_back(i);
}
// 查找元素中是否有9
bool ret = binary_search(v.begin(), v.end(), 9);
if (ret)
{
cout << "找到了!" << endl;
}
else
{
cout << "未找到!" << endl;
}
v.push_back(2); // 如果是无序的序列,结果是未知的
ret = binary_search(v.begin(), v.end(), 9);
if (ret)
{
cout << "找到了!" << endl;
}
else
{
cout << "未找到!" << endl;
}
}
int main()
{
test_01();
system("pause");
return 0;
}
结果:
⑤ count
原型:
- 统计元素出现次数
- begin 开始迭代器
- end 结束迭代器
- value 统计的元素
注意:
/*----------------------------------------------------------------
* 项目: Classical Question
* 作者: Fioman
* 邮箱: geym@hengdingzhineng.com
* 时间: 2022/3/22
* 格言: Talk is cheap,show me the code ^_^
//----------------------------------------------------------------*/
#include <iostream>
using namespace std;
#include<algorithm>
#include<vector>
#include<string>
class Person
{
public:
Person(string name, int age)
{
this->mName = name;
this->mAge = age;
}
// 根据年龄作为比较规则
bool operator==(const Person p)
{
return this->mAge == p.mAge;
}
public:
string mName;
int mAge;
};
// 1. 统计内置数据类型
// 2. 统计自定义的数据类型的个数
void test_01(void)
{
vector<int> v;
for (int i = 0; i < 10; i++)
{
v.push_back(i);
}
v.push_back(1);
v.push_back(1);
int num = count(v.begin(), v.end(), 1);
cout << "1 的元素个数: " << num << endl;
Person p1("A", 10);
Person p2("B", 20);
Person p3("C", 10);
Person p4("D", 10);
Person p5("E", 30);
vector<Person> v2;
v2.push_back(p1);
v2.push_back(p2);
v2.push_back(p3);
v2.push_back(p4);
v2.push_back(p5);
// 如果是要统计年龄相等的话
num = count(v2.begin(), v2.end(), p1);
cout << "和p1年龄相同的人数: " << num << endl;
}
int main()
{
test_01();
system("pause");
return 0;
}
⑥ count_if
原型:
- 按照条件统计元素出现的次数
- begin 开始迭代器
- end 结束迭代器
- _Pred 谓词 (可以是普通的函数,也可以是仿函数(函数对象))
/*----------------------------------------------------------------
* 项目: Classical Question
* 作者: Fioman
* 邮箱: geym@hengdingzhineng.com
* 时间: 2022/3/22
* 格言: Talk is cheap,show me the code ^_^
//----------------------------------------------------------------*/
#include <iostream>
using namespace std;
#include<vector>
#include<algorithm>
bool greater_five(int val)
{
return val > 5;
}
class GreaterSix
{
public:
// 创建谓词
bool operator()(int val)
{
return val > 6;
}
};
void test_01(void)
{
vector<int> v;
for (int i = 0; i < 10; i++)
{
v.push_back(i);
}
// 普通的函数作为判断条件
int num = count_if(v.begin(), v.end(), greater_five);
cout << "大于5的个数: " << num << endl;
// 谓词作为判断条件
num = count_if(v.begin(), v.end(), GreaterSix());
cout << "大于6的个数: " << num << endl;
}
int main()
{
test_01();
system("pause");
return 0;
}
四. 常用的排序算法
① sort
原型:
sort(iterator begin,iterator end,_Pred);
- begin: 开始迭代器
- end: 结束迭代器
- _Pred: 谓词
/*----------------------------------------------------------------
* 项目: Classical Question
* 作者: Fioman
* 邮箱: geym@hengdingzhineng.com
* 时间: 2022/3/22
* 格言: Talk is cheap,show me the code ^_^
//----------------------------------------------------------------*/
#include <iostream>
using namespace std;
#include<vector>
#include<algorithm>
void print_vector(const vector<int>& v)
{
for (vector<int>::const_iterator it = v.begin(); it != v.end(); it++)
{
cout << *it << " ";
}
cout << endl;
}
bool my_compare(int a, int b)
{
return a > b;
}
class MyCompare
{
public:
// 创建谓词
bool operator()(int v1, int v2)
{
return abs(v1) > abs(v2);
}
};
void test_01(void)
{
vector<int> v;
v.push_back(10);
v.push_back(20);
v.push_back(40);
v.push_back(50);
v.push_back(30);
// 默认排序,从小到大
cout << "默认排序: " << endl;
sort(v.begin(), v.end());
print_vector(v);
// 指定排序规则,先使用普通的函数去指定,降序排列
cout << "普通的函数指定降序排列: " << endl;
sort(v.begin(), v.end(), my_compare);
print_vector(v);
// 添加几个负数,然后按照谓词,按照绝对值的升序进行排列
v.push_back(-10);
v.push_back(-20);
v.push_back(-30);
v.push_back(-40);
cout << "谓词按照绝对值降序进行排序: " << endl;
sort(v.begin(), v.end(), MyCompare());
print_vector(v);
}
int main()
{
test_01();
system("pause");
return 0;
}
结果:
② random_shuffle
原型:
- 指定范围内的元素的随机调整次序
- begin 开始迭代器
- end 结束迭代器
/*----------------------------------------------------------------
* 项目: Classical Question
* 作者: Fioman
* 邮箱: geym@hengdingzhineng.com
* 时间: 2022/3/22
* 格言: Talk is cheap,show me the code ^_^
//----------------------------------------------------------------*/
#include <iostream>
using namespace std;
#include<vector>
#include<algorithm>
void print_vector(const vector<int>& v)
{
for (vector<int>::const_iterator it = v.begin(); it != v.end(); it++)
{
cout << *it << " ";
}
cout << endl;
}
void test_01(void)
{
vector<int> v;
for (int i = 0; i < 10; i++)
{
v.push_back(i);
}
print_vector(v);
// 打乱顺序
random_shuffle(v.begin(), v.end());
cout << "顺序打乱以后: " << endl;
print_vector(v);
}
int main()
{
test_01();
system("pause");
return 0;
}
④ merge
原型:
- 容器元素合并,并存储到另外一个容器中
- 注意: 两个容器必须是有序的,合并之后依旧是有序的.并且要提前给dest分配内存空间,使用resize.
- begin1 容器1的开始迭代器
- end1 容器1的结束迭代器
- begin2 容器2的开始迭代器
- end2 容器2的结束迭代器
- dest 目标容器的开始迭代器
/*----------------------------------------------------------------
* 项目: Classical Question
* 作者: Fioman
* 邮箱: geym@hengdingzhineng.com
* 时间: 2022/3/22
* 格言: Talk is cheap,show me the code ^_^
//----------------------------------------------------------------*/
#include <iostream>
using namespace std;
#include<vector>
#include<algorithm>
void my_print(int val)
{
cout << val << " ";
}
void print_vector(const vector<int> &v)
{
for_each(v.begin(), v.end(), my_print);
cout << endl;
}
void test_01(void)
{
vector<int> v1;
vector<int> v2;
for (int i = 0; i < 10; i++)
{
v1.push_back(i);
v2.push_back(i + 1);
}
// 进行合并
vector<int> vTarget;
// 注意: 合并之前,首先是要分配内存空间,注意最后一个参数不是目标容器,而是目标容器的起始迭代器
vTarget.resize(v1.size() + v2.size());
merge(v1.begin(), v1.end(), v2.begin(), v2.end(), vTarget.begin());
cout << "合并后: " << endl;
print_vector(vTarget);
}
int main()
{
test_01();
system("pause");
return 0;
}
⑤ reverse算法
原型:
- 翻转制动范围内的元素
- begin 开始迭代器
- end 结束迭代器
/*----------------------------------------------------------------
* 项目: Classical Question
* 作者: Fioman
* 邮箱: geym@hengdingzhineng.com
* 时间: 2022/3/22
* 格言: Talk is cheap,show me the code ^_^
//----------------------------------------------------------------*/
#include <iostream>
using namespace std;
#include<vector>
#include<algorithm>
void my_print(int val)
{
cout << val << " ";
}
void print_vector(const vector<int> &v)
{
for_each(v.begin(), v.end(), my_print);
cout << endl;
}
void test_01(void)
{
vector<int> v;
for (int i = 0; i < 10; i++)
{
v.push_back(i);
}
// 原容器
cout << "原容器: " << endl;
print_vector(v);
// 打乱顺序
random_shuffle(v.begin(), v.end());
cout << "打乱顺序: " << endl;
print_vector(v);
// 反转
reverse(v.begin(), v.end());
cout << "反转: " << endl;
print_vector(v);
}
int main()
{
test_01();
system("pause");
return 0;
}
结果:
五. 常用的拷贝和替换算法
① copy
原型:
- 拷贝容器到目标容器,需要指定目标容器的大小,也就是说需要使用resize()指定目标容器大小
- begin 开始迭代器
- end 结束迭代器
- dest 目标起始迭代器
/*----------------------------------------------------------------
* 项目: Classical Question
* 作者: Fioman
* 邮箱: geym@hengdingzhineng.com
* 时间: 2022/3/22
* 格言: Talk is cheap,show me the code ^_^
//----------------------------------------------------------------*/
#include <iostream>
using namespace std;
#include<vector>
#include<algorithm>
void my_print(int val)
{
cout << val << " ";
}
void print_vector(const vector<int> &v)
{
for_each(v.begin(), v.end(), my_print);
cout << endl;
}
void test_01(void)
{
vector<int> v1;
vector<int> v2;
for (int i = 0; i < 10; i++)
{
v1.push_back(i);
}
v2.resize(v1.size()-2); // 这个resize之后的大小,要保证可以存放拷贝过来的元素
//v2.resize(v1.size()); // 这种情况下,如果拷贝过来的数据,不到size()大小,默认是填充0,后面
// v2.resize(v1.size() - 3); //空间不够,会报错
// 将v1的内容,拷贝到v2当中,并且去除掉收尾
copy(++v1.begin(), --v1.end(),v2.begin());
cout << "v1 = " << endl;
print_vector(v1);
cout << "v2 = " << endl;
print_vector(v2);
}
int main()
{
test_01();
system("pause");
return 0;
}
结果:
② replace
原型:
- 将区间内旧元素,替换成新元素
- begin 开始迭代器
- end 结束迭代器
- oldValue 旧元素
- newValue 新元素
/*----------------------------------------------------------------
* 项目: Classical Question
* 作者: Fioman
* 邮箱: geym@hengdingzhineng.com
* 时间: 2022/3/22
* 格言: Talk is cheap,show me the code ^_^
//----------------------------------------------------------------*/
#include <iostream>
using namespace std;
#include<vector>
#include<algorithm>
void print_vector(const vector<int> & v)
{
for (vector<int>::const_iterator it = v.begin(); it != v.end(); it++)
{
cout << *it << " ";
}
cout << endl;
}
void test_01(void)
{
vector<int> v;
for (int i = 0; i < 10; i++)
{
v.push_back(i % 3);
}
cout << "原容器: " << endl;
print_vector(v);
// 将容器中的0全部替换为30
replace(v.begin(), v.end(), 0, 30);
cout << "替换后的容器: " << endl;
print_vector(v);
}
int main()
{
test_01();
system("pause");
return 0;
}
③ replace_if
原型:
- 按照条件替换元素,满足条件的替换成指定元素
- begin 开始迭代器
- end 结束迭代器
- _pred 谓词 (或者是普通的函数)
- newValue 替换的新元素
/*----------------------------------------------------------------
* 项目: Classical Question
* 作者: Fioman
* 邮箱: geym@hengdingzhineng.com
* 时间: 2022/3/22
* 格言: Talk is cheap,show me the code ^_^
//----------------------------------------------------------------*/
#include <iostream>
using namespace std;
#include<vector>
#include<algorithm>
void my_print(int val)
{
cout << val << " ";
}
void print_vector(const vector<int> &v)
{
for_each(v.begin(), v.end(), my_print);
cout << endl;
}
bool change_val(int val)
{
return val % 2 == 0;
}
class ChangeVal
{
public:
ChangeVal()
{
}
// 创建谓词,如果是奇数,返回True
bool operator()(int val)
{
if (val % 2 != 0)
{
mCount++;
}
return val % 2 != 0;
}
static int mCount;
};
int ChangeVal::mCount = 0;
void test_01(void)
{
vector<int> v;
for (int i = 0; i < 10; i++)
{
v.push_back(i);
}
cout << "原容器: " << endl;
print_vector(v);
// 使用普通函数作为判断条件,进行替换,将所有的偶数都变成0
replace_if(v.begin(), v.end(), change_val,0);
cout << "将偶数全部变为0之后: " << endl;
print_vector(v);
// 使用谓词,将所有的奇数都变成-1,并且统计奇数的个数
ChangeVal change_val = ChangeVal();
replace_if(v.begin(), v.end(),change_val, -1); // 注意这里调用的不是change_val是change_val的一个副本
// 使用完就消失了,所以这里统计的个数依旧是0,如果想要正确的统计,要使用static
cout << "替换后: 奇数的个数: " << change_val.mCount << endl;
print_vector(v);
}
int main()
{
test_01();
system("pause");
return 0;
}
结果:
④ swap
原型:
- 互换两个容器的元素
- c1的容器1
- c2的容器2
/*----------------------------------------------------------------
* 项目: Classical Question
* 作者: Fioman
* 邮箱: geym@hengdingzhineng.com
* 时间: 2022/3/22
* 格言: Talk is cheap,show me the code ^_^
//----------------------------------------------------------------*/
#include <iostream>
using namespace std;
#include<algorithm>
#include<vector>
void my_print(int val)
{
cout << val << " ";
}
void test_01(void)
{
vector<int> v1;
vector<int> v2;
for (int i = 0; i < 10; i++)
{
i % 2 == 0 ? v1.push_back(i) : v2.push_back(i);
}
cout << "互换前: " << endl;
cout << "v1 = ";
for_each(v1.begin(), v1.end(), my_print);
cout << endl;
cout << "v2 = ";
for_each(v2.begin(), v2.end(), my_print);
cout << endl;
// 交换元素
v1.swap(v2);
cout << "互换后: " << endl;
cout << "v1 = ";
for_each(v1.begin(), v1.end(), my_print);
cout << endl;
cout << "v2 = ";
for_each(v2.begin(), v2.end(), my_print);
cout << endl;
}
int main()
{
test_01();
system("pause");
return 0;
}
六. 常用的算术生成算法
计算区间内容器之和: accumulate
函数原型:
- 计算容器元素累计总和
- begin 开始迭代器
- end 结束迭代器
- value 起始值
- func 为操作方式,默认是使用plus进行相加,如果是自定义的数据类型,需要自己添加操作符
注意:
/*----------------------------------------------------------------
* 项目: Classical Question
* 作者: Fioman
* 邮箱: geym@hengdingzhineng.com
* 时间: 2022/3/22
* 格言: Talk is cheap,show me the code ^_^
//----------------------------------------------------------------*/
#include <iostream>
using namespace std;
#include<vector>
#include<numeric>
class Person
{
public:
Person(string name, int score)
{
this->mName = name;
this->mScore = score;
}
public:
string mName;
int mScore;
};
int person_add(int val, const Person &p)
{
return val + p.mScore;
}
void test_01(void)
{
// 内置类型的求和
vector<int> v;
for (int i = 0; i < 10; i++)
{
v.push_back(i);
}
// 求和
cout << "v的所有元素之和: " << accumulate(v.begin(), v.end(), 0) << endl;
// 自定义类型的求和
Person p1("A", 68);
Person p2("B", 79);
Person p3("C", 90);
Person p4("D", 100);
vector<Person> v2;
v2.push_back(p1);
v2.push_back(p2);
v2.push_back(p3);
v2.push_back(p4);
// 求平均分,因为是自定义类型,要重载加号运算符
int sumScore = accumulate(v2.begin(), v2.end(), 0,person_add);
cout << "总分: " << sumScore << " 平均分: " << sumScore / v2.size() << endl;
}
int main()
{
test_01();
system("pause");
return 0;
}
fill算法
原型:
- 想容器中填充元素
- begin 开始迭代器
- end 结束迭代器
- value 填充的值
/*----------------------------------------------------------------
* 项目: Classical Question
* 作者: Fioman
* 邮箱: geym@hengdingzhineng.com
* 时间: 2022/3/22
* 格言: Talk is cheap,show me the code ^_^
//----------------------------------------------------------------*/
#include <iostream>
using namespace std;
#include<vector>
#include<numeric>
#include<algorithm>
class MyPrint
{
public:
void operator()(float val)
{
cout << val << " ";
}
};
void test_01(void)
{
vector<float> v;
for (int i = 0; i < 10; i++)
{
v.push_back(i);
}
cout << "原容器: " << endl;
for_each(v.begin(), v.end(), MyPrint());
cout << endl;
// 除了两头,将中间的全部填充为平均值
float aver = accumulate(v.begin(), v.end(), 0) /float(v.size());
cout << "aver: " << aver << endl;
fill(++v.begin(), --v.end(), aver);
cout << "填充平均值后: " << endl;
for_each(v.begin(), v.end(), MyPrint());
cout << endl;
}
int main()
{
test_01();
system("pause");
return 0;
}
七. 常用的集合算法
① set_intersection
原型:
注意:
/*----------------------------------------------------------------
* 项目: Classical Question
* 作者: Fioman
* 邮箱: geym@hengdingzhineng.com
* 时间: 2022/3/22
* 格言: Talk is cheap,show me the code ^_^
//----------------------------------------------------------------*/
#include <iostream>
using namespace std;
#include<vector>
#include<algorithm>
void print_vector(const vector<int> &v)
{
for (int i = 0; i < v.size(); i++)
{
cout << v[i] << " ";
}
cout << endl;
}
void test_01(void)
{
vector<int> v1;
vector<int> v2;
for (int i = 0; i < 10; i++)
{
v1.push_back(i); // 0~9
v2.push_back(i + 5);// 5 ~ 14
}
cout << " v1 = ";
print_vector(v1);
cout << "v2 = ";
print_vector(v2);
vector<int> vTarget;
// 需要开辟内存空间,最大需要容量为v1和v2的size的最小值
vTarget.resize(min(v1.size(), v2.size()),-1000);
set_intersection(v1.begin(), v1.end(), v2.begin(), v2.end(), vTarget.begin());
// 求完交集以后,要把后面默认的-1000多出来的元素删除掉
vector<int>::iterator it = find(vTarget.begin(), vTarget.end(), -1000);
if(it != vTarget.end())
{
vTarget.erase(it, vTarget.end());
}
cout << "v1 和 v2 的交集 = ";
print_vector(vTarget);
}
int main()
{
test_01();
system("pause");
return 0;
}
② set_union
原型:
- 求两个集合的并集
- 两个集合必须是有序的序列
- begin1 容器1的起始迭代器
- end1 容器1的结束迭代器
- begin2 容器2的起始迭代器
- end2 容器2的结束迭代器
- dest 目标容器的起始迭代器
注意:
- 两个容器必须有序(并且是升序,亲测过,倒序不行)
- 目标容器需要指定大小, 大小定义为两个size()之和
- 如果并集小于目标容器,目标容器末尾会默认填充0,可以填充一个不在集合1和集合2的值,最后删除掉
/*----------------------------------------------------------------
* 项目: Classical Question
* 作者: Fioman
* 邮箱: geym@hengdingzhineng.com
* 时间: 2022/3/22
* 格言: Talk is cheap,show me the code ^_^
//----------------------------------------------------------------*/
#include <iostream>
using namespace std;
#include<vector>
#include<algorithm>
class MyPrint
{
public:
void operator()(int val)
{
cout << val << " ";
}
};
void test_01(void)
{
vector<int> v1;
vector<int> v2;
for (int i = 0; i < 10; i++)
{
v1.push_back(i); // 0~9
v2.push_back(i + 8); // 8 ~ 17
}
//reverse(v1.begin(), v1.end()); // 倒序不行
//reverse(v2.begin(),v2.end()); // 倒序不行
// 求并集
cout << "v1 = ";
for_each(v1.begin(), v1.end(), MyPrint());
cout << endl;
cout << "v2 = ";
for_each(v2.begin(), v2.end(), MyPrint());
cout << endl;
cout << "v1 和 v2 的并集: " << endl;
vector<int> vTarget;
// 目标容器的最大size是v1的size和v2的size之和,这个时候v1和v2没有重复元素
vTarget.resize(v1.size() + v2.size(), -1000);
// 求并集
set_union(v1.begin(), v1.end(), v2.begin(), v2.end(), vTarget.begin());
vector<int>::iterator it = find(vTarget.begin(), vTarget.end(), -1000);
if (it != vTarget.end())
{
vTarget.erase(it, vTarget.end());
}
for_each(vTarget.begin(), vTarget.end(), MyPrint());
cout << endl;
}
int main()
{
test_01();
system("pause");
return 0;
}
③ set_difference
原型:
- 两个集合必须是有序的(必须是升序)
- begin1 容器1的开始迭代器
- end2 容器1的结束迭代器
- begin2 容器2的开始迭代器
- end2 容器2的结束迭代器
- dest 目标容器的开始迭代器
注意:
- 差集是有顺序的v1和v2的差集, v2和v1的差集的结果大部分的时候都是不一样的
- 差集计算的时候,两个集合必须是升序,然后结果也是升序
/*----------------------------------------------------------------
* 项目: Classical Question
* 作者: Fioman
* 邮箱: geym@hengdingzhineng.com
* 时间: 2022/3/22
* 格言: Talk is cheap,show me the code ^_^
//----------------------------------------------------------------*/
#include <iostream>
using namespace std;
#include<algorithm>
#include<vector>
class MyPrint
{
public:
void operator()(int val)
{
cout << val << " ";
}
};
void test_01(void)
{
vector<int> v1;
vector<int> v2;
for (int i = 0; i < 10; i++)
{
v1.push_back(i); // 0~9
v2.push_back(i + 5); // 5 ~ 14;
}
cout << "v1 = ";
for_each(v1.begin(), v1.end(), MyPrint());
cout << endl;
cout << "v2 = ";
for_each(v2.begin(), v2.end(), MyPrint());
cout << endl;
vector<int> vTarget;
vTarget.resize(max(v1.size(), v2.size()),-1000);
set_difference(v1.begin(), v1.end(), v2.begin(), v2.end(), vTarget.begin());
// 求v1和v2的差集,并且去除掉后面的无效值
vector<int>::iterator it = find(vTarget.begin(), vTarget.end(), -1000);
if (it != vTarget.end())
{
vTarget.erase(it, vTarget.end());
}
cout << "v1 和 v2 的差集: ";
for_each(vTarget.begin(), vTarget.end(), MyPrint());
cout << endl;
vTarget.resize(max(v1.size(), v2.size()), -1000);
// 求v2和v1的差集
set_difference(v2.begin(), v2.end(), v1.begin(), v1.end(), vTarget.begin());
it = find(vTarget.begin(), vTarget.end(), -1000);
if (it != vTarget.end())
{
vTarget.erase(it, vTarget.end());
}
cout << "v2 和 v1 的差集: ";
for_each(vTarget.begin(), vTarget.end(), MyPrint());
cout << endl;
}
int main()
{
test_01();
system("pause");
return 0;
}
结果: