C++常用的STL及方法 (下)

2021/4/10 18:15:01

本文主要是介绍C++常用的STL及方法 (下),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

前言

C++常用的STL及方法 (上) : https://www.cnblogs.com/ICeVe/p/14527347.html

C++常用的 STL 及方法 (中上) : https://www.cnblogs.com/ICeVe/p/14531259.html

C++常用的 STL 及方法 (中) : https://www.cnblogs.com/ICeVe/p/14533812.html

C++常用的 STL 及方法 (中下) : https://www.cnblogs.com/ICeVe/p/14535257.html

目录

  • STL -- 泛型算法
    • <algorithm>
      • max() -- 求最大值
      • min() -- 求最小值
      • abs() -- 求绝对值
      • swap() -- 交换两个值
      • reverse() -- 反转容器
      • next_permutation() -- 求一次排列
      • fill() -- 为容器写入新值
      • sort() -- 对容器进行升序排序
      • find() -- 查找元素
      • count() -- 求出元素出现的次数
      • accumlate() -- 求和
      • lower_bound() -- 通过二分法找到第一个小于等于指定元素的元素
      • upper_bound() -- 通过二分法找到第一个大于指定元素的元素

STL -- 泛型算法

C++中的 <algorithm> 提供了非常多的算法, 使用这些算法能极大的提高编程效率.


algorithm

algorithm 中提供的算法大多数对迭代器有要求, 且需要 STL <iterator> 的支持. 下面来介绍几种常见的迭代器类型.

迭代器大致可分为 5 类 :

    • 输入迭代器

    • 输出迭代器

    • 前向迭代器

    • 双向迭代器

    • 随机访问迭代器

输入迭代器

输入迭代器一般使用 istream_iterator, 其需要 STL <iterator> 的支持

操作 解释
istream_iterator<typename> in(is) in 从输入流 is (一般为 cin ) 读取 typename 类型的值
istream_iterator<typename> end 读取类型为 typename 的 istream_iterator 迭代器, 表示尾后位置
in1 == in2, in1 != in2 用来检查迭代器是否绑定的是相同的输入. 且 in1 和 in2 的 typename 必须相同.
*in 返回从流中读取的值
in -> mem 与 (*in).mem含义相同
++in, in++ 从输入流读取下一个值

下面用一个 accumulate 函数来演示 istream_iterator 的操作

#include <iostream>
#include <iterator>
#include <algorithm>
#include <numeric>

using namespace std;

int main(void)
{
    istream_iterator<int> in(cin);	/*输入1 2 3 4 5 e */
    istream_iterator<int> end;

    cout << *in << endl;
    cout << *(++in) << endl;
    cout << accumulate(in, end, 0) << endl;	/* accumulate 接受一个输入流迭代器和结束输入流迭代器, 最后是起始值*/

    return 0;
}

输出结果

1
2
14	/*迭代器发生了移动, 因此为14*/

  • 返回迭代器目录


输出迭代器

输出流迭代器一般使用 ostream_iterator. 其需要 STL <iterator> 的支持

操作 解释
ostream_iterator<typename> out(os) out 将类型为 typename 的值写到输入流 os ( 一般为cout )中
ostream_iterator<typename> out(os, d) out 将类型为 typename 的值写到输入流 os 中, 每个输出后面有个字符串 d
out = val 将 val 写入到 out 所绑定 os 中来输出结果, 其中 out 和 val 的类型必须兼容

下面用一个 vector 输出的例子来演示 ostream_iterator

#include <iostream>
#include <iterator>
#include <vector>

using namespace std;

int main(void)
{
    vector<int> V{1, 2, 3, 4, 5};
    ostream_iterator<int> out(cout, " ");

    for(auto i : V)
        out = i;
    cout << endl;

    return 0;
}

输出结果

1 2 3 4 5

  • 返回迭代器目录


前向迭代器

顾名思义就是迭代器只能往一个方向移动, 例如 foward_list 使用的迭代器前向迭代器.

  • 返回迭代器目录


双向迭代器

顾名思义就是迭代器可以双向移动, 例如 list 使用的迭代器就是双向迭代器. 该迭代器支持单向迭代器操作

  • 返回迭代器目录


随机访问迭代器

该迭代器的特点是元素可以使用下标访问, 迭代器之间可以相加相减, 这是单向迭代器和部分双向迭代器 (如 list ) 所做不到的.

常见的有 <vector>, <string>, <deque>, <array> 所用的迭代器

该迭代器支持单向和双向迭代器操作

  • 返回迭代器目录


max()

用途 : 求出两者的最大值

一般形式 :

max(val1, val2, cmp);

/* val1 和 val2 为变量或常量, cmp 为二元谓词, 可视情况添加. 返回类型由 val1 和 val2 决定*/

#include <iostream>
#include <algorithm>

using namespace std;

int main(void)
{

    cout << max(1, 2) << endl;

    return 0;
}

输出结果

2

  • 返回目录


min()

用途 : 求出两者的最小值

一般形式 :

min(val1, val2, cmp);

/* val1 和 val2 为变量或常量, cmp为二元谓词, 可视情况添加. 返回类型由 val1 和 val2 决定*/

#include <iostream>
#include <algorithm>

using namespace std;

int main(void)
{

    cout << min(1, 2) << endl;

    return 0;
}

输出结果

1

  • 返回目录


abs()

用途 : 求绝对值

一般形式 :

abs(val);

/* val1 为变量或常量, 返回类型由 val 决定*/

#include <iostream>
#include <algorithm>

using namespace std;

int main(void)
{
    cout << abs(-1.4) << endl;

    return 0;
}

输出结果

1.4

  • 返回目录


swap()

用途 : 交换两个者的值

一般形式 :

swap(x, y);

/* x 和 y 为变量. 返回类型为 void */

输出结果

#include <iostream>
#include <algorithm>

using namespace std;

int main(void)
{
    int x = 2;
    int y = 1;

    swap(x, y);

    cout << x << ' ' << y << endl;

    return 0;
}

输出结果

1
2

  • 返回目录


reverse()

用途 : 反转容器

一般形式 :

reverse(begin, end);

/* begin 和 end 限定范围. 返回类型为 void . 需要双向迭代器 */

#include <iostream>
#include <algorithm>
#include <array>

using namespace std;

int main(void)
{
    array<int, 10> A{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

    reverse(A.begin(), A.end() - 3);

    for (auto i : A)
        cout << i << ' ';
    cout << endl;

    return 0;
}

输出结果

7 6 5 4 3 2 1 8 9 10

  • 返回目录


next_permutation()

用途 : 求一次排列

一般形式 :

next_permutation(begin, end, cmp);

/* begin 和 end 限定范围. cmp 为二元谓词, 可视情况添加. 返回类型为 bool. 需要双向迭代器*/

#include <iostream>
#include <algorithm>
#include <array>

using namespace std;

int main(void)
{
    array<int, 3> A{1, 2, 3};

    for (int i = 0; i < 6; i++)
    {
        for (auto j : A)
            cout << j << ' ';
        next_permutation(A.begin(), A.end());
        cout << endl;
    }

    return 0;
}

输出结果

1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1

  • 返回目录


fill()

用途 : 为容器的某一范围写入新值.

一般形式 :

fill(begin, end, val);

/*  begin 和 end 限定范围. val 为变量或常量. 返回类型为 void */

#include <iostream>
#include <algorithm>
#include <array>

using namespace std;

int main(void)
{
    array<int, 10> A{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

    fill(A.begin(), A.end() - 5, 4);

    for (auto i : A)
        cout << i << ' ';
    cout << endl;

    return 0;
}

输出结果

4 4 4 4 4 6 7 8 9 10

  • 输出结果


sort()

用途 : 对容器进行升序排序

一般形式 :

sort(begin, end, cmp);

/* begin 和 end 限定范围. cmp 为二元谓词, 可以视情况添加. 返回类型为 void */

#include <iostream>
#include <algorithm>
#include <array>

using namespace std;

int main(void)
{
    array<int, 10> A{10, 9, 8, 7, 6, 5, 4, 3, 2, 1};

    sort(A.begin(), A.end());

    for(auto i : A)
        cout << i << ' ';
    cout << endl;

    return 0;
}

输出结果

1 2 3 4 5 6 7 8 9 10

  • 返回目录


find()

用途 : 查找元素

一般形式 :

find(begin, end, val);

/* begin 和 end 限定范围. val 为要查找的元素. 返回一个指向该元素的迭代器*/

#include <iostream>
#include <algorithm>
#include <array>

using namespace std;

int main(void)
{
    array<int, 10> A{10, 9, 8, 7, 6, 5, 4, 3, 2, 1};

    auto i = find(A.begin(), A.end(), 4);

    cout << *i << endl;

    return 0;
}

输出结果

4

  • 返回目录


count()

用途 : 求出元素在容器中出现的次数.

一般形式 :

count(begin, end, val);

/* begin 和 end 限定范围. val 为要需要求的元素. 返回类型为 ptrdiff_t */

#include <iostream>
#include <algorithm>
#include <array>

using namespace std;

int main(void)
{
    array<int, 10> A{10, 10, 10, 4, 5, 5, 2, 1, 1, 0};

    cout << count(A.begin(), A.end(), 10) << endl;
    cout << count(A.begin(), A.end(), 4) << endl;
    cout << count(A.begin(), A.end(), 5) << endl;
    cout << count(A.begin(), A.end(), 2) << endl;
    cout << count(A.begin(), A.end(), 1) << endl;
    cout << count(A.begin(), A.end(), 0) << endl;

    return 0;
}

输出结果

3
1
2
1
2
1

  • 返回目录


accumulate()

用途 : 求和. 需要 STL <numeric>, 可以使用输入迭代器.

一般形式 :

accumulate(begin, end, init);

/* begin 和 end 限定范围, 或者是输入迭代器. init 为初始值. 返回类型为 int */

#include <iostream>
#include <algorithm>
#include <array>
#include <numeric>
#include <iterator>

using namespace std;

int main(void)
{
    array<int, 5> A{1, 2, 3, 4, 5};

    cout << accumulate(A.begin(), A.end(), 0) << endl;

    return 0;
}

输出结果

15

  • 返回目录


lower_bound()

用途 : 通过二分法找到第一个小于等于指定元素的元素. 容器最好是有序的

一般形式 :

lower_bound(begin, end, val, cmp);

/*
begin 和 end 限定范围. val 为要查找的元素. cmp为二元谓词, 可视情况添加. 
返回一个小于等于 val 的元素的迭代器
*/

#include <iostream>
#include <algorithm>
#include <array>
#include <numeric>

using namespace std;

int main(void)
{
    array<int, 5> A{1, 2, 3, 4, 5};

    auto i = lower_bound(A.begin(), A.end(), 4);

    cout << *i << endl;

    return 0;
}

输出结果

4

  • 返回目录


upper_bound()

用途 : 通过二分法找到第一个大于指定元素的元素. 容器最好是有序的

一般形式 :

upper_bound(begin, end, val, cmp);

/*
begin 和 end 限定范围. val 为要查找的元素. cmp 为二元谓词, 可视情况添加. 
返回一个大于 val 的元素的迭代器
*/

#include <iostream>
#include <algorithm>
#include <array>
#include <numeric>

using namespace std;

int main(void)
{
    array<int, 5> A{1, 2, 3, 4, 5};

    auto i = upper_bound(A.begin(), A.end(), 3);

    cout << *i << endl;

    return 0;
}

输出结果

4

  • 返回目录


参考:

  1. <<算法笔记>> -- 胡凡, 曾磊
  2. <<C++ Primer>> -- Stanley B. Lippman


这篇关于C++常用的STL及方法 (下)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程