STL 算法

1. Copying Elements

OutputIter

copy(InputIter sourceBeg, InputIter sourceEnd,

        OutputIter destBeg);

OutputIter

copy_if(InputIter sourceBeg, InputIter sourceEnd,

           OutputIter destBeg,

            UnaryPre op);

OutputIter

copy_n(InputIter sourceBeg,

           Size num,

           OutputIter destBeg);

BidirectionalIter

copy_backward(BidirectionalIter sourceBeg, BidirectionalIter sourceEnd,

                      BidirectionalIter destEnd);

算法复制源区间或num个元素到目的区间。

返回值:目的区间最后一个被复制的元素之后的位置,即第一个没有被重写的元素。

copy():deskEnd不属于[sourceBeg, sourceEnd)。

copy_backward(): deskEnd不属于(sourceBeg, sourceEnd]。

copy_if():source和dest区间不能重复。

注意:使用copy()复制子区间到前面,destBeg必须在sourceBeg之前。

        使用copy_backward()复制子区间到后面,destEnd必须在sourceEnd之后。

类似算法选择:

(1) 源区间不再用时:move()代替copy(), move_backward()代替copy_backward()。

(2) 谓词取反时:用remove_copy_if()。

(3)反向复制:reverse_copy(),可能比copy()使用反向迭代器更有效率。

(4)复制容器元素:同种类型迭代器用assign operator(顺序和关联容器都可以),不同类型用assign成员函数(只能顺序容器)或者成员insert()(顺序(必须有pos)和关联容器)。

(5)复制时移除元素:remove_copy(), remove_copy_if()。

(6)复制时更改元素:transform()或者replace_copy()。

(7) 分割复制:partition_copy(),复制元素为两个区间,一个满足谓词,一个不满足。

2. Moving Elements

OutputIter

move(InputIter sourceBeg, InputIter sourceEnd,

         OutputIter destBeg);

BidirectionalIter

move_backward(BidirectionalIter sourceBeg, BidirectionalIter sourceEnd,

                       BidirectionalIter destEnd);

两个算法move元素到目的区间。

调用:*destElem = std::move(*sourceElem);

返回值:第一个未被重写的元素。

示例:

#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <list>
#include <iterator>
using namespace std;

int main(void)
{
    vector<string> svec{ "Hello", "this", "is", "an", "example" /*1, 2, 3, 4, 5*/ };

    list<string> slist;
    move(svec.begin(), svec.end(), back_inserter(slist));

    //move(slist.begin(), slist.end(), ostream_iterator<string>(cout, " "));

    cout << "svec:" << svec.size() << ":" << svec.capacity() << endl;
    for (auto &elem : svec) {
        cout << elem << " ";
    }
    cout << endl;

    cout << "slist.size() = " << slist.size() << endl;
    cout << "slist 元素:";
    for (auto &elem : slist) {
        cout << elem << " ";
    }
    cout << endl;

    string str = move(*slist.begin());
    cout << "str=" << str << endl;
    cout << "slist.begin()=" << *slist.begin() << endl;

    system("pause");
    return 0;
}

3. for_each和transorm函数

3.1.for_each(),既可作为不可变算法也可作为可变算法。

可能被基于区间的循环所取代。

UnaryProc

for_each(InputIter beg, InputIter end, UnaryProc op);

为区间的每个元素调用op(elem)。

线性复杂度: numElems calls of op()。

3.2.transform()提供了两种能力:

(1)4个参数的,转换源区间的元素到目的区间。复制和更改元素一步完成。

(2)5个参数,结合两个源区间的元素和把结果写入目的区间。

OutputIter

transform(InputIter sourceBeg, InputIter sourceEnd

                OutputIter destBeg,

                UnaryFunc op);

返回值:目的区间最后一个被转换的元素之后的位置,即第一个没有被重写结果的元素。

源区间和目的区间可以相同。

替换指定元素:可以使用replace()。

线性复杂度。

 

OutputIter

transform(InputIter source1Beg, InputIter source1End,

              InputIter source2Beg,

              OutputIter destBeg,

              BinaryFunc op)

两个源区间调用op(source1Elem, source2Elem),将结果写入destBeg中。

返回值:第一个没有被重写结果的元素。

source1Beg, source2Beg和destBeg可能是相同的。

线性复杂度。

posted on 2014-07-04 21:40  hancmhi  阅读(225)  评论(0编辑  收藏  举报