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

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

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替换为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;
}

输出结果:

替换前:
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-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;
}

输出结果:

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-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;
}

输出结果:

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-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;
}

输出结果:

v1和v2的差集为:
0 1 2 3 4
v2和v1的差集为:
10 11 12 13 14
请按任意键继续. . .
  • 22
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值