STL算法定义在两个头文件中,分别是algorithm和numeric。

另人费解的命名???

search/search_n与find_end都是用于查找序列,分别表示在范围1中查找范围2序列的第一次出现,和在范围1中查找范围2序列的最后一次出现。显然属于一对相似操作,但是却用了完全不同的命名。我觉得元素的查找用find,范围的查找用search。哪位读者了解背景可以帮我解释一下?

排列算法

next_permutation、prev_permutation、is_permutation
输出123的各种排列

    string str("123");
    do
    {
        cout << str << endl;
    }while(next_permutation(str.begin(), str.end()));

next_permutation当排列最大时返回false。
prev_permutation当排列最小时返回false。
is_permutation判断一个序列是否是另一序列的一个排列。

用一个或两个序列设置另一个序列transform

int main()
{
    vector<int> v({1, 2, 3});
    list<int> v2(v.size());
    list<int> v3;

    transform(v.begin(), v.end(), v2.begin(), [](int a){return a * 2;}); //v2 = v * 2
    
    //v3 = v * v2因为v3为空,所以这里使用了插入器
    transform(v.begin(), v.end(), v2.begin(), back_inserter(v3), [](int a, int b){return a * b;});  
    
    for_each(v.begin(), v.end(), [](int a){cout << a << "\t";}); 
    cout <<endl;
    for_each(v2.begin(), v2.end(), [](int a){cout << a << "\t";});
    cout <<endl;
    for_each(v3.begin(), v3.end(), [](int a){cout << a << "\t";});
    cout <<endl;
     
    return 0;
}

生成序列

iota生成递增序列。
generate按自己的意愿生成序列。

class UniqueNum
{
public:
    int operator()()
    {
        return num++;
    }
private:
    static atomic<int> num;
};
atomic<int> UniqueNum::num(123);

int main()
{
    vector<int> arr(5);
    vector<int> arr2(5);

    iota(arr.begin(), arr.end(), 0);
    generate(arr2.begin(), arr2.end(), UniqueNum());

    return 0;
}

heap相关

利用heap算法实现堆排序。这里只是演示相关算法的使用,实际上堆排序,在构造堆之后,可以直接使用sort_heap来实现堆排序。

int main()
{
    vector<int> v({5, 1, 2, 8, 7, 9});
    make_heap(v.begin(), v.end());
    for(int i = 0; i < v.size() - 1; i++)
    {
        pop_heap(v.begin(), v.end() - i);
    }

    for_each(v.begin(), v.end(), [](int a){cout << a << endl;});
    return 0;
}

二分查找

int main()
{
    vector<int> v({1,3,5,5,7,9});
    auto low = lower_bound(v.begin(), v.end(), 5); //第一个5
    auto up = upper_bound(v.begin(), v.end(), 5);  //最后一个5的下一个位置
    cout << distance(v.begin(), low) << endl;
    cout << distance(v.begin(), up) << endl;

    auto mypair = equal_range(v.begin(), v.end(), 5); //返回两个边界,左闭或开。相当于同时调用lower_bound和upper_bound
    cout << distance(v.begin(), mypair.first) << endl;
    cout << distance(v.begin(), mypair.second) << endl;
    
    cout << binary_search(v.begin(), v.end(), 5) << endl; //true
    cout << binary_search(v.begin(), v.end(), 6) << endl; //false
    return 0;
}

集合运算

集合算法都是作用于排序序列

算法 结果
merge A + B
inplace_merge(beg, mid, end) A + B,其中A[beg:mid],B[mid,end]。原地求并
set_union (A + B) - (A 交 B)
set_intersection A 交 B
set_difference A - B
set_symmetric_difference (A - B) + (B - A)
includes A是否包含B
    vector<int> arr({1,5,8,9});
    vector<int> arr2({2,5,6,9});

    vector<int> arr3;
    merge(arr.begin(), arr.end(), arr2.begin(), arr2.end(), back_inserter(arr3));
    for (auto &e : arr3) cout << e << "\t"; cout << endl;

    arr3.clear();
    set_union(arr.begin(), arr.end(), arr2.begin(), arr2.end(), back_inserter(arr3));
    for (auto &e : arr3) cout << e << "\t"; cout << endl;

    arr3.clear();
    set_symmetric_difference(arr2.begin(), arr2.end(), arr.begin(), arr.end(),  back_inserter(arr3));
    for (auto &e : arr3) cout << e << "\t"; cout << endl;