PoEdu培训 STL班 第十一课 STL源码解析之算法(一)
文章类别: 培训笔记 0 评论

PoEdu培训 STL班 第十一课 STL源码解析之算法(一)

文章类别: 培训笔记 0 评论

STL之算法(一)

分类

也有按照功能性来分类的

本质

它就是一个模板函数.
拿for_each来说, 不一定要传递一个 迭代器, 我们传递一个 指针 也可以
只要传入的类型 支持 !=, *, ++ 操作即可.

lambda表达式

它其实就是个匿名函数.
以[] 开始, 后跟参数列表, 使用()括起来, 然后是函数体, 使用{}包括.
[]可以捕获变量, 并且可以指定以引用(&)方式, 值(=)方式进行捕获.
再此不在详述.

非变动型算法介绍

all_of

#include <algorithm>
#include <array>

int main()
{

    // all_of
    // 判断是否都是 奇数
    std::array<int, 8> foo = { 3,5,7,11,13,17,19,23 };
    if (std::all_of(foo.begin(), foo.end(), [](int i) {return i % 2; }))
        std::cout << "All the elements are odd numbers.\n";

    return 0;
}

any_of

#include <iostream>     // std::cout
#include <algorithm>    // std::any_of
#include <array>        // std::array

int main () {
  std::array<int,7> foo = {0,1,-1,3,-3,5,-5};
  // 判断是否有负数
  if ( std::any_of(foo.begin(), foo.end(), [](int i){return i<0;}) )
    std::cout << "There are negative elements in the range.\n";

  return 0;
}

none_of

#include <iostream>     // std::cout
#include <algorithm>    // std::none_of
#include <array>        // std::array

int main () {
  std::array<int,8> foo = {1,2,4,8,16,32,64,128};

  // 判断是否都是正数
  if ( std::none_of(foo.begin(), foo.end(), [](int i){return i<0;}) )
    std::cout << "There are no negative elements in the range.\n";

  return 0;
}

for_each

find

#include <iostream>

#include <algorithm>

class Demo
{
    int num_;
public:
    Demo(int num = 0) : num_(num) {}

    bool operator==(int num)
    {
        return num_ == num;
    }
};

int main()
{

    Demo demoArr[10];

    std::find(demoArr, demoArr + sizeof(demoArr) / sizeof(Demo), 20);
    std::find(&demoArr[0], &demoArr[9], 20);

    return 0;
}

例子的情况, 可能无法正确判断.
因为如果查找的元素正好是 demoArr[9], 那么就不知道是否查找到了!
我们换成 &demoArr[10], 或者 demoArr + sizeof(demoArr) / sizeof(Demo) + 1 就可以了.

find_if

find_if_not

find_end

#include <iostream>     // std::cout
#include <algorithm>    // std::find_end
#include <vector>       // std::vector

int main()
{
    int myints[] = { 1,2,3,4,5,1,2,3,4,5 };
    std::vector<int> haystack(myints, myints + 10);

    int needle1[] = { 1,2,3 };

    std::vector<int>::iterator it;
    it = std::find_end(haystack.begin(), haystack.end(), needle1, needle1 + 3);

    if (it != haystack.end())
        std::cout << "needle1 last found at position " << (it - haystack.begin()) << '\n';

    int needle2[] = { 4,5,1 };

    // using predicate comparison:
    it = std::find_end(haystack.begin(), haystack.end(), needle2, needle2 + 3, [](int i, int j) {return (i == j); });

    if (it != haystack.end())
        std::cout << "needle2 last found at position " << (it - haystack.begin()) << '\n';

    return 0;
}

find_first_of

adjacent_find

#include <iostream>     // std::cout
#include <algorithm>    // std::find_end
#include <vector>       // std::vector

int main()
{
    int myints[] = { 5,20,5,30,30,20,10,10,20 };
    std::vector<int> myvector(myints, myints + 8);
    std::vector<int>::iterator it;

    // using default comparison:
    it = std::adjacent_find(myvector.begin(), myvector.end());

    if (it != myvector.end())
        std::cout << "the first pair of repeated elements are: " << *it << '\n';

    //using predicate comparison:
    it = std::adjacent_find(++it, myvector.end(), [](int i, int j) {return i == j; });

    if (it != myvector.end())
        std::cout << "the second pair of repeated elements are: " << *it << '\n';

    return 0;
}

count

count_if

mismatch

#include <iostream>     // std::cout
#include <algorithm>    // std::find_end
#include <vector>       // std::vector

int main()
{
    std::vector<int> myvector;
    for (int i = 1; i<6; i++) myvector.push_back(i * 10); // myvector: 10 20 30 40 50

    int myints[] = { 10,20,80,320,1024 };                //   myints: 10 20 80 320 1024

    std::pair<std::vector<int>::iterator, int*> mypair;

    // using default comparison:
    mypair = std::mismatch(myvector.begin(), myvector.end(), myints);
    std::cout << "First mismatching elements: " << *mypair.first;
    std::cout << " and " << *mypair.second << '\n';

    ++mypair.first; ++mypair.second;

    // using predicate comparison:
    mypair = std::mismatch(mypair.first, myvector.end(), mypair.second, [](int i, int j) {return i == j; });
    std::cout << "Second mismatching elements: " << *mypair.first;
    std::cout << " and " << *mypair.second << '\n';


    return 0;
}

equal

#include <iostream>     // std::cout
#include <algorithm>    // std::equal
#include <vector>       // std::vector

int main()
{
    int myints[] = { 20,40,60,80,100 };               //   myints: 20 40 60 80 100
    std::vector<int>myvector(myints, myints + 5);     // myvector: 20 40 60 80 100

    // using default comparison:
    if (std::equal(myvector.begin(), myvector.end(), myints))
        std::cout << "The contents of both sequences are equal.\n";
    else
        std::cout << "The contents of both sequences differ.\n";

    myvector[3] = 81;                                 // myvector: 20 40 60 81 100

    // using predicate comparison:
    if (std::equal(myvector.begin(), myvector.end(), myints, [](int i, int j) {return (i == j); }))
        std::cout << "The contents of both sequences are equal.\n";
    else
        std::cout << "The contents of both sequences differ.\n";

    return 0;
}

search

search_n

#include <iostream>     // std::cout
#include <algorithm>    // std::search_n
#include <vector>       // std::vector

int main()
{
    int myints[] = { 10,20,30,30,20,10,10,20 };
    std::vector<int> myvector(myints, myints + 8);

    std::vector<int>::iterator it;

    // using default comparison:
    // 搜索出现2次30的地方
    it = std::search_n(myvector.begin(), myvector.end(), 2, 30);

    if (it != myvector.end())
        std::cout << "two 30s found at position " << (it - myvector.begin()) << '\n';
    else
        std::cout << "match not found\n";

    // using predicate comparison:
    // 搜索连续出现2次等于10的地方
    it = std::search_n(myvector.begin(), myvector.end(), 2, 10, [](int i, int j) {return (i == j); });

    if (it != myvector.end())
        std::cout << "two 10s found at position " << int(it - myvector.begin()) << '\n';
    else
        std::cout << "match not found\n";

    return 0;
}

状态判断技法

我们写模板函数的时候, 可以对模板函数进行特化
例如在SGI的代码中, 我们在destroy函数的调用过程中
针对有无析构函数进行了判定
而判定不是用if来完成的, 而是用模板函数特化了true_value和false_value完成的
这样效率高, 可读性好

未完待续...

如有错误,请提出指正!谢谢.

回复