(由于上篇笔记篇幅过长,故开新篇 继续记录算法笔记)
2.3常用排序算法
学习目标:掌握常用的排序算法
算法简介:
sort //对容器内元素进行排序
random_shuffle //洗牌 指定范围内的元素随机调整次序
merge //容器元素合并,并存储到另一容器中
reverse //反转指定范围的元素
2.3.1 sort
功能描述:对容器内元素进行排序
sort属于开发中最常用的算法之一,需熟练掌握
函数原型:
sort(iterator beg, iterator end, _Pred);
// 按值查找元素,找到返回指定位置迭代器,找不到返回结束迭代器位置
// beg 开始迭代器
// end 结束迭代器
// _Pred 谓词
#include <iostream>
using namespace std;
#include<vector>
#include<algorithm>
#include<functional>
//常用排序算法 sort
void myPrint(int val)
{cout << val << " ";
}void test01()
{vector<int>v;v.push_back(10);v.push_back(30);v.push_back(50);v.push_back(20);v.push_back(40);//利用sort进行升序 默认就是升序sort(v.begin(), v.end());for_each(v.begin(), v.end(), myPrint);cout << endl;//利用sort进行降序sort(v.begin(), v.end(),greater<int>());for_each(v.begin(), v.end(), myPrint);cout << endl;
}int main()
{test01();system("pause");return 0;
}
输出结果:
10 20 30 40 50
50 40 30 20 10
请按任意键继续. . .
2.3.2 random_shuffle
功能描述:洗牌 指定范围内的元素随机调整次序
函数原型:
random_shuffle(iterator beg, iterator end);
// 指定范围内的元素随机调整次序
// beg 开始迭代器
// end 结束迭代器
#include <iostream>
using namespace std;
#include<vector>
#include<algorithm>
#include<ctime>
//常用排序算法 random_shuffle
void myPrint(int val)
{cout << val << " ";
}void test01()
{//随机数种子 不然每次洗牌之后的顺序都一样srand((unsigned int)time(NULL));vector<int>v;for (int i = 0; i < 10; i++){v.push_back(i);}//利用洗牌算法 打乱顺序random_shuffle(v.begin(), v.end());for_each(v.begin(), v.end(), myPrint);cout << endl;
}int main()
{test01();system("pause");return 0;
}
输出结果:
9 2 8 1 5 6 4 0 7 3
请按任意键继续. . .
2.3.3 merge
功能描述:两个容器元素合并,并存储到另一容器中
注意:两个容器必须是有序的(而且顺序必须相同,不能一个升序,一个降序)
函数原型:
merge(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest);
// 容器元素合并,并存储到另一容器中
// 注意: 两个容器必须是有序的
// beg1 容器1开始迭代器
// end1 容器1结束迭代器
// beg2 容器2开始迭代器
// end2 容器2结束迭代器
// dest 目标容器开始迭代器
#include <iostream>
using namespace std;
#include<vector>
#include<algorithm>
//常用排序算法 merge
void myPrint(int val)
{cout << val << " ";
}void test01()
{vector<int>v1;vector<int>v2;for (int i = 0; i < 10; i++){v1.push_back(i);v2.push_back(i + 10);}//目标容器vector<int>vTarget;//需要提前给目标容器分配空间//否则会报错vTarget.resize(v1.size() + v2.size());merge(v1.begin(), v1.end(), v2.begin(), v2.end(), vTarget.begin());for_each(vTarget.begin(), vTarget.end(), myPrint);cout << endl;
}int main()
{test01();system("pause");return 0;
}
输出结果:
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
请按任意键继续. . .
2.3.4 reverse
功能描述:将容器内元素进行反转
函数原型:
reverse(iterator beg, iterator end);
// 反转指定范围的元素
// beg 开始迭代器
// end 结束迭代器
#include <iostream>
using namespace std;
#include<vector>
#include<algorithm>
//常用排序算法 reverse
void myPrint(int val)
{cout << val << " ";
}void test01()
{vector<int>v1;for (int i = 0; i < 10; i++){v1.push_back(i);}cout << "反转前:" << endl;for_each(v1.begin(), v1.end(), myPrint);reverse(v1.begin(), v1.end());cout << endl;cout << "反转后:" << endl;for_each(v1.begin(), v1.end(), myPrint);cout << endl;
}int main()
{test01();system("pause");return 0;
}
输出结果:
反转前:
0 1 2 3 4 5 6 7 8 9
反转后:
9 8 7 6 5 4 3 2 1 0
请按任意键继续. . .
2.4常用拷贝和替换算法
学习目标:掌握常用的拷贝和替换算法
算法简介:
copy //容器内指定范围的元素拷贝到另一容器中
replace //将容器内指定范围的旧元素修改为新元素
replace_if //容器内指定范围满足条件的元素替换为新元素
swap //互换两个容器的元素
2.4.1 copy
功能描述:容器内指定范围的元素拷贝到另一容器中
函数原型:
copy(iterator beg, iterator end, iterator dest);
// 按值查找元素,找到返回指定位置迭代器,找不到返回结束迭代器位置
// beg 开始迭代器
// end 结束迭代器
// dest 目标起始迭代器
#include <iostream>
using namespace std;
#include<vector>
#include<algorithm>
//常用拷贝和替换算法 copy
void myPrint(int val)
{cout << val << " ";
}void test01()
{vector<int>v1;for (int i = 0; i < 10; i++){v1.push_back(i);}vector<int>v2;v2.resize(v1.size());copy(v1.begin(), v1.end(), v2.begin());for_each(v2.begin(), v2.end(), myPrint);cout << endl;
}int main()
{test01();system("pause");return 0;
}
输出结果:
0 1 2 3 4 5 6 7 8 9
请按任意键继续. . .
2.4.2 replace
功能描述:将容器内指定范围的旧元素修改为新元素
函数原型:
replace(iterator beg, iterator end, oldvalue, newvalue);
// 将区间内旧元素 替换成 新元素
// beg 开始迭代器
// end 结束迭代器
// oldvalue 旧元素
// newvalue 新元素
#include <iostream>
using namespace std;
#include<vector>
#include<algorithm>
//常用拷贝和替换算法 replace
class MyPrint
{
public:void operator()(int val){cout << val << " ";}
};void test01()
{vector<int>v;v.push_back(20);v.push_back(30);v.push_back(50);v.push_back(30);v.push_back(40);v.push_back(20);v.push_back(10);v.push_back(20);cout << "替换前:" << endl;for_each(v.begin(), v.end(), MyPrint());//将20替换为99replace(v.begin(), v.end(), 20, 99);cout << endl;cout << "替换后:" << endl;for_each(v.begin(), v.end(), MyPrint());cout << endl;
}int main()
{test01();system("pause");return 0;
}
输出结果:
替换前:
20 30 50 30 40 20 10 20
替换后:
99 30 50 30 40 99 10 99
请按任意键继续. . .
2.4.3 replace_if
功能描述:将区间内满足条件的元素,替换成指定元素
注意:利用仿函数可以灵活筛选满足的条件
函数原型:
replace_if(iterator beg, iterator end, _pred, newvalue);
// 按条件替换元素,满足条件的替换成指定元素
// beg 开始迭代器
// end 结束迭代器
// _pred 谓词
// newvalue 替换的新元素
#include <iostream>
using namespace std;
#include<vector>
#include<algorithm>
//常用拷贝和替换算法 replace_if
class MyPrint
{
public:void operator()(int val){cout << val << " ";}
};class Greater03
{
public:bool operator()(int val){return val >= 30;}
};void test01()
{vector<int>v;v.push_back(10);v.push_back(40);v.push_back(20);v.push_back(40);v.push_back(30);v.push_back(50);v.push_back(20);v.push_back(30);cout << "替换前:" << endl;for_each(v.begin(), v.end(), MyPrint());//将大于等于30替换为99//利用仿函数可以灵活筛选满足的条件replace_if(v.begin(), v.end(), Greater03(), 99);cout << endl;cout << "替换后:" << endl;for_each(v.begin(), v.end(), MyPrint());cout << endl;
}int main()
{test01();system("pause");return 0;
}
输出结果:
替换前:
10 40 20 40 30 50 20 30
替换后:
10 99 20 99 99 99 20 99
请按任意键继续. . .
2.4.4 swap
功能描述:互换两个容器的元素
注意:一定要是同种容器
函数原型:
swap(container c1, container c2);
// 互换两个容器的元素
// c1容器1
// c2容器2
#include <iostream>
using namespace std;
#include<vector>
#include<algorithm>
//常用拷贝和替换算法 swap
class MyPrint
{
public:void operator()(int val){cout << val << " ";}
};void test01()
{vector<int>v1;vector<int>v2;for (int i = 0; i < 10; i++){v1.push_back(i);v2.push_back(i + 100);}cout << "交换前:" << endl;for_each(v1.begin(), v1.end(), MyPrint());cout << endl;for_each(v2.begin(), v2.end(), MyPrint());cout << endl;cout << "------------------" << endl;cout << "交换后:" << endl;swap(v1, v2);for_each(v1.begin(), v1.end(), MyPrint());cout << endl;for_each(v2.begin(), v2.end(), MyPrint());cout << endl;
}int main()
{test01();system("pause");return 0;
}
输出结果:
交换前:
0 1 2 3 4 5 6 7 8 9
100 101 102 103 104 105 106 107 108 109
------------------
交换后:
100 101 102 103 104 105 106 107 108 109
0 1 2 3 4 5 6 7 8 9
请按任意键继续. . .
2.5常用算术生成算法
学习目标:掌握常用的算术生成算法
注意:算术生成算法属于小型算法,使用时包含的头文件为#include<numeric>
算法简介:
accumulate // 计算容器元素累计总和
fill // 向容器中添加元素
2.5.1 accumulate
功能描述:计算区间内 容器元素累计总和
函数原型:
accumulate(iterator beg, iterator end, value);
// 计算容器元素累计总和
// beg 开始迭代器
// end 结束迭代器
// value 起始值
#include <iostream>
using namespace std;
#include<vector>
#include<numeric>//别忘了包含此头文件
//常用算术生成算法 accumulate
void test01()
{vector<int>v;for (int i = 0; i <= 100; i++){v.push_back(i);}//参数3是个起始累加值int total = accumulate(v.begin(), v.end(), 0);cout << "total = " << total << endl;
}int main()
{test01();system("pause");return 0;
}
输出结果:
total = 5050
请按任意键继续. . .
2.5.2 fill
功能描述:向容器中填充指定的元素
函数原型:
fill(iterator beg, iterator end, value);
// 向容器中填充元素
// beg 开始迭代器
// end 结束迭代器
// value 填充的值
#include <iostream>
using namespace std;
#include<vector>
#include<numeric>//别忘了包含此头文件
#include<algorithm>
//常用算术生成算法 fill
class MyPrint
{
public:void operator()(int val){cout << val << " ";}
};void test01()
{vector<int>v;v.resize(10);//后期重新填充fill(v.begin(), v.end(), 100);for_each(v.begin(), v.end(), MyPrint());cout << endl;
}int main()
{test01();system("pause");return 0;
}
输出结果:
100 100 100 100 100 100 100 100 100 100
请按任意键继续. . .
2.6常用集合算法
学习目标:掌握常用的集合算法
算法简介:
set_intersection // 求两个容器的交集
set_union //求两个容器的并集
set_difference // 求两个容器的差集
2.6.1 set_intersection
功能描述:求两个容器的交集
注意:
两个集合必须是有序序列
目标容器开辟空间需要从两个容器中取小值
set_intersection返回值是交集中最后一个元素的位置
函数原型:
set_intersection(iterator begl, iterator end1, iterator beg2, iterator end2, iterator dest);
// 求两个集合的交集
// 注意:两个集合必须是有序序列
// beg1 容器1开始迭代器
// end1 容器1结束迭代器
// beg2 容器2开始迭代器
// end2 容器2结束迭代器
// dest 目标容器开始迭代器
#include <iostream>
using namespace std;
#include<vector>
#include<algorithm>
//常用集合算法 set_intersection
class MyPrint
{
public:void operator()(int val){cout << val << " ";}
};void test01()
{vector<int>v1;vector<int>v2;for (int i = 0; i < 10; i++){v1.push_back(i); //0-9v2.push_back(i + 5); //5-14}vector<int>vTarget;//目标容器需要提前开辟空间//最特殊情况,大容器包含小容器,开辟空间,取小容器的size即可vTarget.resize(min(v1.size(), v2.size()));//获取交集//返回值是个迭代器,是最后一个元素的位置vector<int>::iterator itEnd = set_intersection(v1.begin(), v1.end(), v2.begin(), v2.end(), vTarget.begin());//所以这里遍历的时候,容器末尾是itEndfor_each(vTarget.begin(), itEnd, MyPrint());cout << endl;
}int main()
{test01();system("pause");return 0;
}
输出结果:
5 6 7 8 9
请按任意键继续. . .
2.6.2 set_union
功能描述:求两个集合的并集
注意:
两个集合必须是有序序列
目标容器开辟空间需要两个容器相加
set_union返回值既是并集中最后一个元素的位置
函数原型:
set_union(iterator begl, iterator end1, iterator beg2, iterator end2, iterator dest);
// 求两个集合的并集
// 注意:两个集合必须是有序序列
// beg1 容器1开始迭代翳
// end1 容器1结束迭代器
// beg2 容器2开始迭代器
// end2 容器2结束迭代器
// dest 目标容器开始迭代器
#include <iostream>
using namespace std;
#include<vector>
#include<algorithm>
//常用集合算法 set_union
class MyPrint
{
public:void operator()(int val){cout << val << " ";}
};void test01()
{vector<int>v1;vector<int>v2;for (int i = 0; i < 10; i++){v1.push_back(i); //0-9v2.push_back(i + 5); //5-14}vector<int>vTarget;//目标容器需要提前开辟空间//最特殊情况,大容器加上小容器,开辟空间,取两个容器的size和即可vTarget.resize(v1.size() + v2.size());//获取并集//返回值是个迭代器,是最后一个元素的位置vector<int>::iterator itEnd = set_union(v1.begin(), v1.end(), v2.begin(), v2.end(), vTarget.begin());//所以这里遍历的时候,容器末尾是itEndfor_each(vTarget.begin(), itEnd, MyPrint());cout << endl;
}int main()
{test01();system("pause");return 0;
}
输出结果:
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
请按任意键继续. . .
2.6.3 set_difference
功能描述:求两个集合的差集
注意:
求差集的两个集合必须的有序序列
目标容器开辟空间需要从两个容器取较大值
set_difference返回值既是差集中最后一个元素的位置
函数原型:
set_difference(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest);
// 求两个集合的差集
// 注意:两个集合必须是有序序列
// beg1 容器1开始迭代器
// end1 容器1结束迭代器
// beg2 容器2开始迭代器
// end2 容器2结束迭代器
// dest 目标容器开始迭代器
#include <iostream>
using namespace std;
#include<vector>
#include<algorithm>
//常用集合算法 set_difference
class MyPrint
{
public:void operator()(int val){cout << val << " ";}
};void test01()
{vector<int>v1;vector<int>v2;for (int i = 0; i < 10; i++){v1.push_back(i); //0-9v2.push_back(i + 5); //5-14}vector<int>vTarget;//目标容器需要提前开辟空间//最特殊情况,两容器没有交集,开辟空间,取两个容器的最大size即可vTarget.resize(max(v1.size(), v2.size()));//获取差集//返回值是个迭代器,是最后一个元素的位置cout << "v1和v2的差集为:" << endl;vector<int>::iterator itEnd = set_difference(v1.begin(), v1.end(), v2.begin(), v2.end(), vTarget.begin());//所以这里遍历的时候,容器末尾是itEndfor_each(vTarget.begin(), itEnd, MyPrint());cout << endl;cout << "v2和v1的差集为:" << endl;itEnd = set_difference(v2.begin(), v2.end(), v1.begin(), v1.end(), vTarget.begin());//所以这里遍历的时候,容器末尾是itEndfor_each(vTarget.begin(), itEnd, MyPrint());cout << endl;
}int main()
{test01();system("pause");return 0;
}
输出结果:
v1和v2的差集为:
0 1 2 3 4
v2和v1的差集为:
10 11 12 13 14
请按任意键继续. . .