Notes d'étude C++ STL (3) - algorithmes courants
- anecdote
- aperçu
- 1. Algorithmes de traversée couramment utilisés
- 2. Algorithmes de recherche courants
- 3. Algorithmes de tri couramment utilisés
- 4. Algorithmes de copie et de remplacement couramment utilisés
- 5. Algorithmes de génération arithmétique couramment utilisés
- 6. Algorithmes d'ensemble couramment utilisés
anecdote
Ceci est la troisième partie des notes d'étude STL. Les deux premières concernent respectivement les conteneurs et les objets fonctionnels. Partie 1
: Notes d'étude STL (1)—conteneurs
Partie 2 : Notes d'étude STL (2)
aperçu
L'algorithme est principalement composé de fichiers d'en-tête
<algorithm>
,<numeric>
et<functional>
.
<algorithm>
Il s'agit du plus grand de tous les fichiers d'en-tête STL, et les fonctions couramment utilisées impliquent la comparaison, l'échange, la recherche, le parcours, la copie, la modification, l'inversion, le tri, la fusion, etc. Le volume est très petit, ne comprenant que quelques conteneurs de séquence
<numeric>
. fonctions pour des opérations simples, y compris des opérations d'addition et de multiplication sur des séquences.
<functional>
Certaines classes de modèles sont définies pour déclarer des objets fonction
1. Algorithmes de traversée couramment utilisés
for_each// Traverser le conteneur
transform// Déplacer le conteneur vers un autre conteneur
1.1 pour_chacun
/* 遍历算法 遍历容器元素 @param beg 开始迭代器 @param end 结束迭代器 @param _callback 函数回调或者函数对象 @return 函数对象 */ for_each(iterator beg, iterator end, _callback);
Résumé : for_eachLes paramètres ordinaires et les foncteurs peuvent être utilisés ; cependant, seul le nom de la fonction est requis pour utiliser des fonctions ordinaires. Lors de l'utilisation de foncteurs, des objets anonymes des foncteurs sont requis.
void myPrint1(int val){
cout<<val<<" ";
}
class myPrint2{
public:
void operator()(int val){
cout<<val<<" ";
}
};
for_each(v.begin(),v.end(),myPrint1);
for_each(v.begin(),v.end(),myPrint2());
1.2 transformation
Description de la fonction :
déplacer les éléments de la plage de conteneurs spécifiée vers un autre conteneur
Prototype de fonction :/* transform算法 将指定容器区间元素搬运到另一容器中 注意 : transform 不会给目标容器分配内存,所以需要我们提前分配好内存 @param beg1 源容器开始迭代器 @param end1 源容器结束迭代器 @param beg2 目标容器开始迭代器 @param _cakkback 回调函数或者函数对象 @return 返回目标容器迭代器 */ transform(iterator beg1, iterator end1, iterator beg2, _func);
Exemple:
#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
using namespace std;
class myPrint{
//函数用来遍历
public:
void operator()(int val){
cout<<val<<" ";
}
};
class myTransform{
//函数用来 搬运容器的同时对值进行操作
public:
int operator()(int val){
return val+100;
}
};
void test01(){
vector<int>v;
for(int i=0;i<10;i++){
v.push_back(i);
}
vector<int>v2;
v2.resize(v.size());
transform(v.begin(),v.end(),v2.begin(),myTransform());
for_each(v2.begin(),v2.end(),myPrint());
}
int main(){
test01();
system("pause");
return 0;
}
2. Algorithmes de recherche courants
find//Rechercher des éléments
find_if//Rechercher des éléments par conditions
adjacent_find//Rechercher des éléments répétitifs adjacents
binary_search//Méthode de recherche binaire
count//Statistiques Nombre d'éléments
count_if//Statistiques Nombre d'éléments par conditions
2.1 trouver
Description de la fonction:
Recherchez l'élément spécifié, recherchez l'itérateur qui renvoie l'élément spécifié, s'il n'est pas trouvé, renvoyez l'itérateur de fin end()
Prototype de fonction :
find(iterator beg, iterator end, value); // 按值查找元素,找到返回指定位置迭代器,找不到返回结束迭代器位置 // beg 开始迭代器 // end 结束迭代器 // value 查找的元素
Remarque : Le type de données défini par l'utilisateur doit surcharger l'opérateur == lors de la recherche ; il renverra un itérateur, qu'il soit trouvé ou non ;
内置数据类型
vector<int>::iterator it = find(v.begin(),v.end(),5);
if(it != v.end()){
cout<< *it <<endl;
}else
cout<<"not found"<<endl;
自定义数据类型
class Person{
public:
Person(string name,int age):_name(name),_age(age){
}
//重载==
bool operator==(const Person&p) {
if(this->_name == p._name && this->_age == p._age){
return true;
}
else{
return false;
}
}
string _name;
int _age;
};
void test02(){
vector<Person>v;
v.push_back(Person("zhangsan",20));
v.push_back(Person("lisi",30));
v.push_back(Person("wangwu",40));
vector<Person>::iterator it = find(v.begin(),v.end(),Person("lisi",30));
if(it != v.end()){
cout<< it-> _name <<endl;
}else
cout<<"not found"<<endl;
}
2.2 trouver_if
Description de la fonction:
trouver un élément par condition
Prototype de fonction :
find_if(iterator beg, iterator end, _Pred); // 按值查找元素,找到返回指定位置迭代器,找不到返回结束迭代器位置 // beg 开始迭代器// end 结束迭代器 // _Pred 函数或者谓词(返回bool类型的仿函数)
Avis:
内置数据类型
class greaterFive{
public:
bool operator()(int a){
return a>5;
}
};
void test01(){
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 << "没找到!" << endl;
else
cout << "找到大于5的数字:" << *it << endl;
}
自定义数据类型
class Person{
public:
Person(string name, int age):_name(name),_age(age){
}
string _name;
int _age;
};
class greater9{
public:
bool operator()(Person& p){
return p._age>9;
}
};
void test02(){
vector<Person>v;
v.push_back(Person("aaa", 10));
v.push_back(Person("bbb", 20));
v.push_back(Person("ccc", 30));
v.push_back(Person("ddd", 40));
vector<Person>::iterator it = find_if(v.begin(),v.end(),greater9());
cout<<it->_age<<endl;
}
2.3 adjacent_find
Description de la fonction:
Rechercher les éléments en double adjacents
Prototype de fonction :
adjacent_find(iterator beg, iterator end); // 查找相邻重复元素,返回相邻元素的第一个位置的迭代器 // beg 开始迭代器 // end 结束迭代器
2.4 recherche_binaire
Description de la fonction:
Rechercher si l'élément spécifié existe, remarque : non disponible dans les séquences non ordonnées
Prototype de fonction :
bool binary_search(iterator beg, iterator end, value); // 查找指定的元素,查到 返回true 否则false // 注意: 在无序序列中不可用 // beg 开始迭代器 // end 结束迭代器 // value 查找的元素
Remarque : La séquence dite ordonnée fait référence à la séquence disposée du grand au petit ou du petit au grand ; si j'insère un 2 à la fin d'un conteneur qui passe de un à dix, l'algorithme ne peut pas s'appliquer à ce conteneur.
2,5 points
Description de la fonction:
Nombre d'éléments statistiques
Prototype de fonction :
count(iterator beg, iterator end, value); // 统计元素出现次数 // beg 开始迭代器 // end 结束迭代器 // value 统计的元素
统计内置数据类型
int num=count(v.begin(),v.end(),10);
cout<<num<<endl;
统计自定义数据类型
class Person{
public:
Person(int id,string name):_id(id),_name(name){
}
bool operator==(const Person& p){
if(p._id==this->_id)
return true;
else
return false;
}
int _id;
string _name;
};
//怎么用
int num=count(v.begin(), v.end(), Person(3,"adsf")) ;
2.6 compte_if
Description de la fonction:
compter les occurrences d'éléments par condition
Prototype de fonction :
count_if(iterator beg, iterator end,_Pred); // 按条件统计元素出现次数 // beg 开始迭代器 // end 结束迭代器 // _Pred 谓词
Puisque les exemples de cette section sont fondamentalement les mêmes que ceux de la section find_if, je ne les écrirai pas ;
3. Algorithmes de tri couramment utilisés
Introduction à l'algorithme :
sort// Trier les éléments dans le conteneur
random_shuffle// Mélanger les éléments dans la plage spécifiée pour ajuster l'ordre de manière aléatoire
merge// Les éléments du conteneur sont fusionnés et stockés dans un autre conteneur
reverse// Inverser les éléments dans la plage spécifiée
3.1 trier
Description de la fonction:
Trier les éléments dans le conteneur
prototype de fonction
sort(iterator beg, iterator end, _Pred); //按值查找元素,找到返回指定位置迭代器,找不到返回结束迭代器位置 //beg 开始迭代器 //end 结束迭代器 /*_Pred 谓词,不写默认升序排列; 需要一个返回值是bool类型的()重载 也可以是STL内部的函数对象 */
sort(v1.begin(),v1.end());
for(auto i:v1) cout<<i<<" ";
cout<<endl;
sort(v1.begin(), v1.end(),greater<int>());
for(auto i:v1) cout<<i<<" ";
cout<<endl;
3.2 random_shuffle
Description de la fonction random_shuffle :
Mélangez les éléments dans la plage spécifiée pour ajuster l'ordre de manière aléatoire
Prototype de fonction :
random shuffle(iterator beg, iterator end); //指定范围内的元素随机调整次序 //beg 开始迭代器 //end 结束迭代器
Cet algorithme de brouillage s'appuie sur la graine de fonction aléatoire, donc une graine aléatoire doit être ajoutée lors de son utilisation srand((unsigned int)time(NULL));pour garantir que les résultats de chaque brouillage sont différents. N'oubliez pas d'inclure time.hle fichier d'en-tête
/*示例*/
#include<time.h>
void test02(){
srand((unsigned int)time(NULL));//随机数种子
vector<int> v1;
for(int i=0;i<10;i++)
v1.push_back(i);
random_shuffle(v1.begin(), v1.end());
for(auto i : v1)
cout << i << " ";
}
3.3 fusion
Description de la fonction de fusion :
两个容器元素合并,并存储到另一容器中
函数原型:
merge(iterator beg1,iterator end1,iterator beg2,iterator end2,iterator dest); //容器元素合并,并存储到另一容器中 //注意:两个容器必须是有序的 //beg1 容器1开始迭代器 //end1 容器1结束迭代器 //beg2 容器2开始迭代器 //end2 容器2结束迭代器 //dest 目标容器开始迭代器
警告:
①两个容器应均为有序序列,且排序方式相同
②在用目标容器之前需要提前给目标容器分配空间
vTarget.resize(v1.size() + v2.size());
merge(v1.begin(), v1.end(), v2.begin(), v2.end(), vTarget.begin());
3.4 reverse
reverse 功能描述:
将容器内元素进行反转, 反转指定范围的元素
函数原型:
reverse(iterator beg, iterator end); //反转指定范围的元素 //beg开始迭代器 //end结束迭代器
4.常用拷贝和替换算法
算法简介:
copy//容器内指定范围的元素拷贝到另一容器中
replace//将容器内指定范围的旧元素修改为新元素
replace_if //容器内指定范围满足条件的元素替换为新元素
swap //互换两个容器的元素
4.1 copy
copy 功能描述:
容器内指定范围的元素拷贝到另一容器中
函数原型:
copy(iterator beg,iterator end,iterator dest); //beg开始迭代器 //end结束迭代器 //dest目标起始迭代器
注意:
dest应该提前 reszie 分配空间
意义不大,可以直接用=赋值;
4.2 replace
replace 功能描述
将区间内旧元素 替换成 新元素
函数原型:
replace(iterator beg,iterator end,oldvalue,newvalue) //将区间内旧元素 替换成 新元素 //beg开始迭代器 //end结束迭代器 //oldvalue 旧元素 //newvalue 新元素
#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>
class MyPrint{
public:
void operator()(int val){
cout << val << " ";
}
};
//常用拷贝和替换算法 replace
void test01(){
vector<int>v;
v.push_back(20);
v.push_back(30);
v.push_back(50);
v.push_back(20);
v.push_back(40);
cout << "替换前:" << endl;
for_each(v.begin(), v.end(), MyPrint());
cout << endl;
//将20替换为2000
replace(v.begin(), v.end(),20,2000);
cout << "替换后:" << endl;
for_each(v.begin(), v.end(), MyPrint());
cout << endl;
}
int main() {
test01();
system("pause");
return 0;
}
4.3 replace_if
replace 功能描述
将区间内满足条件的旧元素 替换成 新元素,需要重载()符号
函数原型:
replace_if(iterator beg,iterator end,_pred,newvalue) //将区间内旧元素 替换成 新元素 //beg开始迭代器 //end结束迭代器 //_pred 谓词 重载()符号 //newvalue 新元素
4.4 swap
swap 功能描述
互换两个容器的元素,应是两个相同类型的容器
函数原型:
swap(container c1,container c2); //将区间内旧元素 替换成 新元素 //互换两个容器的元素 //c1容器1 //c2容器2
5.常用算术生成算法
注意:
算术生成算法属于小型算法,使用时包含头文件为#include< numeric>
算法简介:
accumulate//计算区间内 容器元素累计总和
fill //向容器中添加元素
5.1 accumulate
accumulate 功能描述
计算容器元素累计总和
函数原型:
accumulate<iterator beg,iterator end,value> //beg开始迭代器 //end结束迭代器 //value 起始值
例子:
int total = accumulate(v.begin(),v.end(),0);
5.2 fill
fill 功能描述
向容器中填充元素
函数原型:
fill(iterator beg,iterator end,value) //向容器中填充元素 //beg开始迭代器 //end结束迭代器 //value 填充的值
例子:
fill(v.begin(), v.end(), 100);
注意:如果容器没有分配空间应该先分配空间再调用此函数
6.常用集合算法
算法简介:
set_intersection //求两个容器的交集
set_union//求两个容器的并集
set_difference //求两个容器的差集
6.1 set_intersection
set_intersection 功能描述
求两个集合的交集,两个集合必须是有序序列
函数原型:
set_intersection(iterator beg1,iterator end1,iterator beg2,iterator end2,iterator dest); //求两个容器的交集 //beg1容器1开始迭代器 //end1容器1结束迭代器 //beg2容器2开始迭代器 //end2容器2结束迭代器 //dest 目标容器开始迭代器
例子:
vTarget.resize(min(v1.size(), v2.size()));
vector::iterator itEnd = set_intersection(v1.begin(), v1.end(), v2.begin(), v2.end(), vTarget.begin());
注意:目标容器应该提前开辟空间(取小容器的size)
两个集合必须是有序序列
会返回交集中最后一个元素的位置
6.2 set_union
set_union 功能描述
求两个集合的并集
函数原型:
set_union(iterator beg1,iterator end1,iterator beg2,iterator end2,iterator dest); //求两个容器的并集 //beg1容器1开始迭代器 //end1容器1结束迭代器 //beg2容器2开始迭代器 //end2容器2结束迭代器 //dest 目标容器开始迭代器
例子:
vTarget.resize(v1.size() + v2.size());
vector::iterator itEnd = vector::iterator itEnd = set_union(v1.begin(), v1.end(), v2.begin(), v2.end(), vTarget.begin());
注意:
两个集合必须是有序序列
特殊情况 两个大容器没有交集,并集就是两个容器size相加
会返回交集中最后一个元素的位置
6.3 set_difference
功能描述:
求两个集合的差集
函数原型:
set_difference(iterator beg1,iterator end1,iterator beg2,iterator end2,iterator dest); //求两个集合的差集 //注意:两个集合必须是有序序列 //beg1容器1开始迭代器 //end1容器1结束迭代器 //beg2容器2开始迭代器 //end2容器2结束迭代器 //dest 目标容器开始迭代器
例子:
vTarget.resize(max(v1.size() , v2.size()));
vector::iterator itEnd = vector::iterator itEnd = set_difference(v1.begin(), v1.end(), v2.begin(), v2.end(), vTarget.begin());
注意:
两个集合必须是有序序列
特殊情况 两个大容器没有交集,并集就是取大的size
会返回交集中最后一个元素的位置