目录
1--STL常用算法的概述
STL 提供的常用算法主要由头文件<algorithm>、<functional> 和 <numeric> 组成;
<algorithm> 是STL所有头文件中最大的一个,其范围涉及比较、交换、查找、遍历操作、复制和修改等;
<numeric> 只包括几个在序列上面进行简单数学运算的模板函数;
<functional> 定义了一些模板类,用以声明函数对象;
2--常用遍历算法
2-1--for_each
for_each 常用于遍历容器,其基本用法如下:
#include "iostream"
#include "vector"
#include "algorithm"
void MyPrint1(int val){
std::cout << val << " ";
}
class MyPrint2{
public:
void operator()(int val){
std::cout << val << " ";
}
};
int main(int argc, char* argv[]){
std::vector<int> v1;
for(int i = 0; i < 10; i++){
v1.push_back(i);
}
// 普通函数
for_each(v1.begin(), v1.end(), MyPrint1);
std::cout << std::endl;
// 函数对象
for_each(v1.begin(), v1.end(), MyPrint2());
std::cout << std::endl;
return 0;
}
2-2--transform
transform 用于将一个容器的元素搬运到另一个容器中,其函数原型如下:
transform(iterator beg1, iterator end1, iterator beg2, _func);
// beg1 表示源容器的开始迭代器;
// end1 表示源容器的结束迭代器;
// beg2 表示目标容器的开始迭代器;
// _func 表示函数或函数对象;
代码实例:
#include "iostream"
#include "vector"
#include "algorithm"
class MyTransform{
public:
int operator()(int val){
return val + 100;
}
};
class MyPrint{
public:
void operator()(int val){
std::cout << val << " ";
}
};
int main(int argc, char* argv[]){
std::vector<int> v1;
for(int i = 0; i < 10; i++){
v1.push_back(i);
}
std::vector<int> v2;
v2.resize(v1.size());
// 将容器 1 的元素按指定规则搬运到容器 2
transform(v1.begin(), v1.end(), v2.begin(), MyTransform());
// 函数对象
for_each(v1.begin(), v1.end(), MyPrint());
std::cout << std::endl;
for_each(v2.begin(), v2.end(), MyPrint());
std::cout << std::endl;
return 0;
}
3--常用查找算法
STL 提供的常用查找算法如下:
find // 查找元素
find_if // 按条件查找元素
adjacent_find // 查找相邻重复元素
binary_search // 二分查找法
count // 统计元素个数
count_if // 按条件统计元素个数
3-1--find
find() 用于查找指定元素,找到则返回指定元素的迭代器,找不到则返回结束迭代器 end();find() 的函数原型如下:
find(iterator beg, iterator end, value);
// beg 开始迭代器
// end 结束迭代器
// value 查找的元素
3-1-1--查找内置类型元素
#include "iostream"
#include "vector"
#include "algorithm"
void test1(){
std::vector<int> v;
for(int i = 0; i < 10; i++){
v.push_back(i);
}
std::vector<int>::iterator it = find(v.begin(), v.end(), 5);
if(it != v.end()){
std::cout << "Find the Elem: " << *it << std::endl;
}
else{
std::cout << "Can not Find the Elem." << std::endl;
}
}
int main(int argc, char* argv[]){
test1();
return 0;
}
3-1-2--查找自定义类型元素
查找自定义类型元素时,需要重载自定义类型的 == 操作符,便于调用 find() 函数进行比较;
#include "iostream"
#include "vector"
#include "algorithm"
#include "string"
class Person{
public:
Person(std::string name, int age){
this->Name = name;
this->Age = age;
}
// 重载 == 号, 便于find()函数进行比较
bool operator==(const Person &p){
if(this->Name == p.Name && this->Age == p.Age){
return true;
}
else{
return false;
}
}
std::string Name;
int Age;
};
void test2(){
Person p1("Zhangsan", 10);
Person p2("Lisi", 20);
Person p3("Wangwu", 30);
Person p4("Zhaoliu", 40);
std::vector<Person> v;
v.push_back(p1);
v.push_back(p2);
v.push_back(p3);
v.push_back(p4);
Person test_p("Zhangsan", 10);
std::vector<Person>::iterator it = find(v.begin(), v.end(), test_p);
if(it != v.end()){
std::cout << "Find the Elem. " << " Name: " << (*it).Name
<< " Age: " << (*it).Age << std::endl;
}
else{
std::cout << "Can not Find the Elem." << std::endl;
}
}
int main(int argc, char* argv[]){
test2();
return 0;
}
3-2--find_if
find_if() 用于按条件查找元素,找到则返回指定位置迭代器,未找到则返回结束迭代器的位置,其函数原型如下:
find_if(iterator beg, iterator end, _Pred);
// beg 表示开始迭代器
// end 表示结束迭代器
// _Pred 表示函数或者谓词(即返回 bool 类型的仿函数)
3-2-1--查找内置类型元素
#include "iostream"
#include "vector"
#include "algorithm"
#include "string"
class MyGreater{
public:
bool operator()(int val){
return val > 5;
}
};
int main(int argc, char* argv[]){
std::vector<int> v;
for(int i = 0; i < 10; i++){
v.push_back(i);
}
std::vector<int>::iterator it = find_if(v.begin(), v.end(), MyGreater());
if(it != v.end()){
std::cout << "Find the Elem: " << *it << std::endl;
}
else{
std::cout << "Can not Find the Elem." << std::endl;
}
return 0;
}
3-2-2--查找自定义类型元素
#include "iostream"
#include "vector"
#include "algorithm"
#include "string"
class Person{
public:
Person(std::string name, int age){
this -> Name = name;
this -> Age = age;
}
std::string Name;
int Age;
};
class MyGreater{
public:
bool operator()(Person &p){
return p.Age > 20;
}
};
int main(int argc, char* argv[]){
Person p1("Zhangsan", 10);
Person p2("Lisi", 20);
Person p3("Wangwu", 30);
Person p4("Zhaoliu", 40);
std::vector<Person> v;
v.push_back(p1);
v.push_back(p2);
v.push_back(p3);
v.push_back(p4);
std::vector<Person>::iterator it = find_if(v.begin(), v.end(), MyGreater());
if(it != v.end()){
std::cout << "Find the Elem. " << " Name: " << (*it).Name
<< " Age: " << (*it).Age << std::endl;
}
else{
std::cout << "Can not Find the Elem." << std::endl;
}
return 0;
}
3-3--adjacent_find
adjacent_find() 查找相邻的重复元素,若找到则返回相邻元素的第一个位置的迭代器,未找到则返回结束迭代器 end(),其函数原型如下:
adjacent_find(iterator beg, iterator end);
// beg 表示开始迭代器
// end 表示结束迭代器
实例代码:
#include "iostream"
#include "vector"
#include "algorithm"
#include "string"
int main(int argc, char* argv[]){
std::vector<int> v;
v.push_back(0);
v.push_back(1);
v.push_back(2);
v.push_back(3);
v.push_back(4);
v.push_back(4);
std::vector<int>::iterator it = adjacent_find(v.begin(), v.end());
if(it != v.end()){
std::cout << "Find the Elem: " << *it << std::endl;
}
else{
std::cout << "Can not Find the Elem." << std::endl;
}
return 0;
}
3-4--binary_search
binary_search 用于查找指定元素是否存在,若找到则返回true,未找到则返回false,其函数原型如下:
bool binary_search(iterator beg, iterator end, value);
// beg 表示开始迭代器
// end 表示结束迭代器
// value 表示查找的元素
// 需要强调的是,binary_search 在无序序列中不可使用;
代码实例:
#include "iostream"
#include "vector"
#include "algorithm"
#include "string"
int main(int argc, char* argv[]){
std::vector<int> v;
for(int i = 0; i < 10; i++){
v.push_back(i);
}
bool ret = binary_search(v.begin(), v.end(), 5);
if(ret){
std::cout << "Find the Elem." << std::endl;
}
else{
std::cout << "Can not Find the Elem." << std::endl;
}
return 0;
}
3-5--count
count 用于统计元素个数,其函数原型如下:
count(iterator beg, iterator end, value);
// beg 表示开始迭代器
// end 表示结束迭代器
// value 表示统计的元素
3-5-1--统计内置类型元素
#include "iostream"
#include "vector"
#include "algorithm"
#include "string"
int main(int argc, char* argv[]){
std::vector<int> v;
v.push_back(10);
v.push_back(20);
v.push_back(20);
v.push_back(30);
v.push_back(30);
v.push_back(30);
int num10 = count(v.begin(), v.end(), 10);
int num20 = count(v.begin(), v.end(), 20);
int num30 = count(v.begin(), v.end(), 30);
std::cout << "num10: " << num10 << " num20: " << num20
<< " num30: " << num30 << std::endl;
return 0;
}
3-5-2--统计自定义类型元素
#include "iostream"
#include "vector"
#include "algorithm"
#include "string"
class Person{
public:
Person(std::string name, int age){
this->Name = name;
this->Age = age;
}
bool operator==(const Person &p){
if(this->Age == p.Age){
return true;
}
else{
return false;
}
}
std::string Name;
std::string Age;
};
int main(int argc, char* argv[]){
Person p1("aaa", 20);
Person p2("bbb", 20);
Person p3("ccc", 20);
Person p4("ddd", 30);
Person p5("eee", 40);
std::vector<Person> v;
v.push_back(p1);
v.push_back(p2);
v.push_back(p3);
v.push_back(p4);
v.push_back(p5);
Person test_p("fff", 20);
// 统计与 test_p 年龄相同的元素个数
int num = count(v.begin(), v.end(), test_p);
std::cout << "num: " << num << std::endl;
return 0;
}
3-6--count_if
3-6-1--统计内置类型元素
#include "iostream"
#include "vector"
#include "algorithm"
#include "string"
class MyGreater{
public:
bool operator()(int val){
return val > 20;
}
};
int main(int argc, char* argv[]){
std::vector<int> v;
v.push_back(10);
v.push_back(20);
v.push_back(30);
v.push_back(40);
v.push_back(50);
int num = count_if(v.begin(), v.end(), MyGreater());
std::cout << "Num: " << num << std::endl;
return 0;
}
3-6-2--统计自定义类型元素
#include "iostream"
#include "vector"
#include "algorithm"
#include "string"
class Person{
public:
Person(std::string name, int age){
this->Name = name;
this->Age = age;
}
std::string Name;
int Age;
};
class MyGreater{
public:
bool operator()(const Person &p){
return (p.Age > 20);
}
};
int main(int argc, char* argv[]){
Person p1("aaa", 20);
Person p2("bbb", 20);
Person p3("ccc", 20);
Person p4("ddd", 30);
Person p5("eee", 40);
std::vector<Person> v;
v.push_back(p1);
v.push_back(p2);
v.push_back(p3);
v.push_back(p4);
v.push_back(p5);
// 统计年龄大于 20 的元素个数
int num = count_if(v.begin(), v.end(), MyGreater());
std::cout << "Num: " << num << std::endl;
return 0;
}
4--常用排序算法
STL 提供了如下常用的排序算法:
sort // 对容器内元素进行排序
random_shuffle // 洗牌,对指定范围内的元素进行随机调整次序
merge // 容器元素合并,并存储到另一个容器当中
reverse // 反转指定范围的元素
4-1--sort
sort()对容器内的元素进行排序,其函数原型如下:
sort(iterator beg, iterator end, _Pred);
// beg 开始迭代器
// end 结束迭代器
// _Pred 谓词
代码实例:
#include "iostream"
#include "vector"
#include "algorithm"
#include "functional"
void MyPrint(int val){
std::cout << val << " ";
}
class MyCompare{
public:
bool operator()(int v1, int v2){
return v1 > v2;
}
};
int main(int argc, char* argv[]){
std::vector<int> v;
v.push_back(10);
v.push_back(30);
v.push_back(20);
v.push_back(50);
v.push_back(40);
// 默认从小到大(升序)
sort(v.begin(), v.end());
for_each(v.begin(), v.end(), MyPrint);
std::cout << std::endl;
// 自定义从大到小的排序规则
sort(v.begin(), v.end(), MyCompare());
for_each(v.begin(), v.end(), MyPrint);
std::cout << std::endl;
// 使用STL提供的降序仿函数
sort(v.begin(), v.end(), std::greater<int>());
for_each(v.begin(), v.end(), MyPrint);
std::cout << std::endl;
return 0;
}
4-2--random_shuffle
random_shuffle() 用于给指定范围内的元素进行随机调整次序,其函数原型如下:
random_shuffle(iterator beg, iterator end);
// beg 表示开始迭代器
// end 表示结束迭代器
代码实例:
#include "iostream"
#include "vector"
#include "algorithm"
#include "ctime"
void MyPrint(int val){
std::cout << val << " ";
}
int main(int argc, char* argv[]){
srand((unsigned int)time(NULL)); // 设置随机种子
std::vector<int> v;
for(int i = 0; i < 10; i++){
v.push_back(i);
}
for_each(v.begin(), v.end(), MyPrint);
std::cout << std::endl;
random_shuffle(v.begin(), v.end());
for_each(v.begin(), v.end(), MyPrint);
std::cout << std::endl;
return 0;
}
4-3--merge
merge() 用于将两个容器元素进行合并,并存储在另一个容器当中,其函数原型如下:
merge(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest);
// beg1 表示容器1的开始迭代器
// end1 表示容器1的结束迭代器
// beg2 表示容器2的开始迭代器
// end2 表示容器2的结束迭代器
// dest 表示目标容器的开始迭代器
// 注:容器1和容器2必须是有序的
代码实例:
#include "iostream"
#include "vector"
#include "algorithm"
void MyPrint(int val){
std::cout << val << " ";
}
int main(int argc, char* argv[]){
std::vector<int> v1;
std::vector<int> v2;
for(int i = 0; i < 10; i++){
v1.push_back(i);
v2.push_back(i+1);
}
for_each(v1.begin(), v1.end(), MyPrint);
std::cout << std::endl;
for_each(v2.begin(), v2.end(), MyPrint);
std::cout << std::endl;
std::vector<int> v3;
v3.resize(v1.size()*2);
merge(v1.begin(), v1.end(), v2.begin(), v2.end(), v3.begin());
for_each(v3.begin(), v3.end(), MyPrint);
std::cout << std::endl;
return 0;
}
4-4--reverse
reverse() 将容器内的元素进行反转,其函数原型如下:
reverse(iterator beg, iterator end);
// 反转指定范围的容器
// beg 开始迭代器
// end 结束迭代器
代码实例:
#include "iostream"
#include "vector"
#include "algorithm"
void MyPrint(int val){
std::cout << val << " ";
}
int main(int argc, char* argv[]){
std::vector<int> v1;
v1.push_back(10);
v1.push_back(30);
v1.push_back(20);
v1.push_back(40);
// before reverse
std::cout << "Before Reverse: " << std::endl;
for_each(v1.begin(), v1.end(), MyPrint);
std::cout << std::endl;
// after reverse
std::cout << "After Reverse: " << std::endl;
reverse(v1.begin(), v1.end());
for_each(v1.begin(), v1.end(), MyPrint);
std::cout << std::endl;
return 0;
}