C++提高笔记(七)---STL常用算法(排序、拷贝和替换、算术生成、集合)

(由于上篇笔记篇幅过长,故开新篇 继续记录算法笔记)

2.3常用排序算法

**学习目标:**掌握常用的排序算法

算法简介:

cpp 复制代码
sort           //对容器内元素进行排序
random_shuffle //洗牌 指定范围内的元素随机调整次序
merge          //容器元素合并,并存储到另一容器中
reverse        //反转指定范围的元素

2.3.1 sort

**功能描述:**对容器内元素进行排序

sort属于开发中最常用的算法之一,需熟练掌握

函数原型:

cpp 复制代码
sort(iterator beg, iterator end, _Pred);
// 按值查找元素,找到返回指定位置迭代器,找不到返回结束迭代器位置
// beg 开始迭代器
// end 结束迭代器
// _Pred 谓词
cpp 复制代码
#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;
}

输出结果:

cpp 复制代码
10 20 30 40 50
50 40 30 20 10
请按任意键继续. . .

2.3.2 random_shuffle

**功能描述:**洗牌 指定范围内的元素随机调整次序

函数原型:

cpp 复制代码
random_shuffle(iterator beg, iterator end);
// 指定范围内的元素随机调整次序
// beg 开始迭代器
// end 结束迭代器
cpp 复制代码
#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;
}

输出结果:

cpp 复制代码
9 2 8 1 5 6 4 0 7 3
请按任意键继续. . .

2.3.3 merge

**功能描述:**两个容器元素合并,并存储到另一容器中

注意:两个容器必须是有序的(而且顺序必须相同,不能一个升序,一个降序)

函数原型:

cpp 复制代码
merge(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest);
// 容器元素合并,并存储到另一容器中
// 注意: 两个容器必须是有序的
// beg1 容器1开始迭代器
// end1 容器1结束迭代器
// beg2 容器2开始迭代器
// end2 容器2结束迭代器
// dest 目标容器开始迭代器
cpp 复制代码
#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;
}

输出结果:

cpp 复制代码
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
请按任意键继续. . .

2.3.4 reverse

**功能描述:**将容器内元素进行反转

函数原型:

cpp 复制代码
reverse(iterator beg, iterator end);
// 反转指定范围的元素
// beg 开始迭代器
// end 结束迭代器
cpp 复制代码
#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;
}

输出结果:

cpp 复制代码
反转前:
0 1 2 3 4 5 6 7 8 9
反转后:
9 8 7 6 5 4 3 2 1 0
请按任意键继续. . .

2.4常用拷贝和替换算法

**学习目标:**掌握常用的拷贝和替换算法

算法简介:

cpp 复制代码
copy       //容器内指定范围的元素拷贝到另一容器中
replace    //将容器内指定范围的旧元素修改为新元素
replace_if //容器内指定范围满足条件的元素替换为新元素
swap       //互换两个容器的元素

2.4.1 copy

**功能描述:**容器内指定范围的元素拷贝到另一容器中

函数原型:

cpp 复制代码
copy(iterator beg, iterator end, iterator dest);
// 按值查找元素,找到返回指定位置迭代器,找不到返回结束迭代器位置
// beg 开始迭代器
// end 结束迭代器
// dest 目标起始迭代器
cpp 复制代码
#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;
}

输出结果:

cpp 复制代码
0 1 2 3 4 5 6 7 8 9
请按任意键继续. . .

2.4.2 replace

**功能描述:**将容器内指定范围的旧元素修改为新元素

函数原型:

cpp 复制代码
replace(iterator beg, iterator end, oldvalue, newvalue);
// 将区间内旧元素 替换成 新元素
// beg 开始迭代器
// end 结束迭代器
// oldvalue 旧元素
// newvalue 新元素
cpp 复制代码
#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替换为99
    replace(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;
}

输出结果:

cpp 复制代码
替换前:
20 30 50 30 40 20 10 20
替换后:
99 30 50 30 40 99 10 99
请按任意键继续. . .

2.4.3 replace_if

**功能描述:**将区间内满足条件的元素,替换成指定元素

注意:利用仿函数可以灵活筛选满足的条件

函数原型:

cpp 复制代码
replace_if(iterator beg, iterator end, _pred, newvalue);
// 按条件替换元素,满足条件的替换成指定元素
// beg 开始迭代器
// end 结束迭代器
// _pred 谓词
// newvalue 替换的新元素
cpp 复制代码
#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;
}

输出结果:

cpp 复制代码
替换前:
10 40 20 40 30 50 20 30
替换后:
10 99 20 99 99 99 20 99
请按任意键继续. . .

2.4.4 swap

**功能描述:**互换两个容器的元素

注意:一定要是同种容器

函数原型:

cpp 复制代码
swap(container c1, container c2);
// 互换两个容器的元素
// c1容器1
// c2容器2
cpp 复制代码
#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;
}

输出结果:

cpp 复制代码
交换前:
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>**

算法简介:

cpp 复制代码
accumulate // 计算容器元素累计总和
fill       // 向容器中添加元素

2.5.1 accumulate

**功能描述:**计算区间内 容器元素累计总和

函数原型:

cpp 复制代码
accumulate(iterator beg, iterator end, value);
// 计算容器元素累计总和
// beg 开始迭代器
// end 结束迭代器
// value 起始值
cpp 复制代码
#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;
}

输出结果:

cpp 复制代码
total = 5050
请按任意键继续. . .

2.5.2 fill

**功能描述:**向容器中填充指定的元素

函数原型:

cpp 复制代码
fill(iterator beg, iterator end, value);
// 向容器中填充元素
// beg 开始迭代器
// end 结束迭代器
// value 填充的值
cpp 复制代码
#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;
}

输出结果:

cpp 复制代码
100 100 100 100 100 100 100 100 100 100
请按任意键继续. . .

2.6常用集合算法

**学习目标:**掌握常用的集合算法

算法简介:

cpp 复制代码
set_intersection // 求两个容器的交集
set_union        //求两个容器的并集
set_difference   // 求两个容器的差集

2.6.1 set_intersection

**功能描述:**求两个容器的交集

注意:

两个集合必须是 有序序列

目标容器开辟空间需要 从两个容器中取小值

set_intersection 返回值****是交集中 最后一个元素的位置

函数原型:

cpp 复制代码
set_intersection(iterator begl, iterator end1, iterator beg2, iterator end2, iterator dest);
// 求两个集合的交集
// 注意:两个集合必须是有序序列
// beg1 容器1开始迭代器
// end1 容器1结束迭代器
// beg2 容器2开始迭代器
// end2 容器2结束迭代器
// dest 目标容器开始迭代器
cpp 复制代码
#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-9
        v2.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());
    //所以这里遍历的时候,容器末尾是itEnd
    for_each(vTarget.begin(), itEnd, MyPrint());
    cout << endl;
}

int main()
{
    test01();
    system("pause");
    return 0;
}

输出结果:

cpp 复制代码
5 6 7 8 9
请按任意键继续. . .

2.6.2 set_union

**功能描述:**求两个集合的并集

注意:

两个集合必须是有序序列

目标容器开辟空间需要两个容器相加

set_union返回值既是并集中最后一个元素的位置

函数原型:

cpp 复制代码
set_union(iterator begl, iterator end1, iterator beg2, iterator end2, iterator dest);
// 求两个集合的并集
// 注意:两个集合必须是有序序列
// beg1 容器1开始迭代翳
// end1 容器1结束迭代器
// beg2 容器2开始迭代器
// end2 容器2结束迭代器
// dest 目标容器开始迭代器
cpp 复制代码
#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-9
        v2.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());
    //所以这里遍历的时候,容器末尾是itEnd
    for_each(vTarget.begin(), itEnd, MyPrint());
    cout << endl;
}

int main()
{
    test01();
    system("pause");
    return 0;
}

输出结果:

cpp 复制代码
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
请按任意键继续. . .

2.6.3 set_difference

**功能描述:**求两个集合的差集

注意:

求差集的两个集合必须的有序序列

目标容器开辟空间需要从两个容器取较大值

set_difference返回值既是差集中最后一个元素的位置

函数原型:

cpp 复制代码
set_difference(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest);
// 求两个集合的差集
// 注意:两个集合必须是有序序列
// beg1 容器1开始迭代器
// end1 容器1结束迭代器
// beg2 容器2开始迭代器
// end2 容器2结束迭代器
// dest 目标容器开始迭代器
cpp 复制代码
#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-9
        v2.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());
    //所以这里遍历的时候,容器末尾是itEnd
    for_each(vTarget.begin(), itEnd, MyPrint());
    cout << endl;

    cout << "v2和v1的差集为:" << endl;
    itEnd = set_difference(v2.begin(), v2.end(), v1.begin(), v1.end(), vTarget.begin());
    //所以这里遍历的时候,容器末尾是itEnd
    for_each(vTarget.begin(), itEnd, MyPrint());
    cout << endl;
}

int main()
{
    test01();
    system("pause");
    return 0;
}

输出结果:

cpp 复制代码
v1和v2的差集为:
0 1 2 3 4
v2和v1的差集为:
10 11 12 13 14
请按任意键继续. . .
相关推荐
k093313 分钟前
sourceTree回滚版本到某次提交
开发语言·前端·javascript
神奇夜光杯21 分钟前
Python酷库之旅-第三方库Pandas(202)
开发语言·人工智能·python·excel·pandas·标准库及第三方库·学习与成长
Themberfue23 分钟前
Java多线程详解⑤(全程干货!!!)线程安全问题 || 锁 || synchronized
java·开发语言·线程·多线程·synchronized·
plmm烟酒僧25 分钟前
Windows下QT调用MinGW编译的OpenCV
开发语言·windows·qt·opencv
测试界的酸菜鱼36 分钟前
Python 大数据展示屏实例
大数据·开发语言·python
我是谁??36 分钟前
C/C++使用AddressSanitizer检测内存错误
c语言·c++
小码农<^_^>38 分钟前
优选算法精品课--滑动窗口算法(一)
算法
羊小猪~~40 分钟前
神经网络基础--什么是正向传播??什么是方向传播??
人工智能·pytorch·python·深度学习·神经网络·算法·机器学习
晨曦_子画1 小时前
编程语言之战:AI 之后的 Kotlin 与 Java
android·java·开发语言·人工智能·kotlin
Black_Friend1 小时前
关于在VS中使用Qt不同版本报错的问题
开发语言·qt