C++汎用アルゴリズム

10803 ワード

1、汎用アルゴリズムの初期
標準ライブラリアルゴリズムは、少数の例外を除いて、1つの範囲内の要素を操作します.この範囲を「入力範囲」と呼び、処理する最初の要素と最後の要素の後の位置の反復器を表す前の2つのパラメータを常に使用します.
1.1.読み取り専用アルゴリズムは入力範囲内の要素のみを読み取り、要素を変更しない
find
int sum = accumulate(c.begin(),c.end(),0);
string sum = accmulate(strc.begin(),strc.end(),string(""));
string sum = accmulate(strc.begin(),strc.end(),"");//  

読み取り専用で要素を変更しないアルゴリズムでは、通常cbegin()、cend()が使用されます.
2つのシーケンスを操作するアルゴリズム
//c2           c1。
//
equal(c1.begin(),c1.end(),c2.begin());

1.2.ライトコンテナ要素アルゴリズムは、コンテナ操作を実行しないので、コンテナサイズを変更することはできません.
fill(c.begin(),c.end(),0);// 0  。
fill(c.begin(),c.size(),0);


//     
//back_inserter
vector<int> vec;
auto it = back_inserter(vec);
*it = 42;
//   back_inserter       
fill_n(back_inserter(vec),vec.size(),0);

コピーアルゴリズム
//copy
int a1[] = {1,2,3,4,5,6,7,8,9};
int a2[sizeof(a1)/sizeof(*a1)];
auto ret = copy(begin(a1),end(a1),a2);

//replace
replace(c.begin(),c.end(),0,5);//   c  0   5
//replace_copy,        
replace_copy(c.begin(),c.end,back_inserter(ivec),0,5);//ivec c   。

1.3、並べ替えアルゴリズム
sort(c.begin(),c.end());//   c        

auto end_unique = unique(c.begin(),c.end()); //      

2、カスタム操作
2.1、アルゴリズムに関数を渡す
bool isShorter(const string &s1, const string &s2)
{
    return si.size()< s2.size();
}

sort(c.begin(),c.end(),isSorter);

2.2、lambda式
1つのlambda式は、呼び出し可能なコードユニットを表す.名前のないインライン関数として理解できます.
[capture list]->return type{function bodt}[キャプチャリスト]lambdaが存在する関数で定義されたローカル変数のリスト(通常は空)(パラメータリスト)パラメータリストreturn type戻りタイプfunction body関数体
[](const string &s1,const string s2){return s1.size()//             ,             
auto f = []{return 42;};

暗黙的なキャプチャ
[=](const string &s1){return s.size() >= sz;};//=       
[&](const string &s1){return s.size() >= sz;};//&    

//             ,&    ,    ,c    ,   
[&,c](const string &s){os<<s<<c};

ブレンドキャプチャ方式を使用する場合、キャプチャ方式は同じではありません.すなわち、暗黙的なキャプチャが値キャプチャである場合、明示的なキャプチャは参照キャプチャである必要があります.
可変lambda
size_t v1 = 42;
auto f= [v1]()mutable{return ++v1};

Lambda戻りタイプの指定
[](int i) -> int{if(i<0) return -i;else return i;};

2.3、パラメータバインド
bind関数
//arg_list           。     callable   。
auto newCallable = bind(callable, arg_list);
auto check6 = bind(check_size, _1,6);
string s = "hello";
bool b1 = check6(s);//  check6(s)    check_size(s,6);

placeholdersの名前を使う_nはplaceholdersという名前のネーミング空間に定義され、このネーミング空間自体はstdネーミング空間に定義される.これらの名前を使うために、2つのネーミングスペースに書きます.bind、placeholdersはfunctionalヘッダファイルに定義されます.
3、反復器
  • 挿入反復器(insert iterator)は、容器に要素
  • を挿入するために使用することができる.
  • ストリーム反復器(stream iterator)は、入力出力ストリームにバインドされ、関連するIOストリームを遍歴するために使用することができる.
  • 逆反復器(reverse iterator)forward_を除いて、前方ではなく後方に移動Listには逆反復器
  • があります
  • 反復器(move iterator)を移動し、要素を移動します.

  • 3.1、反復器の挿入
    back_inserter front_inserter inserter
    3.2、iostream反復器istream_iterator読み込み入力ストリームostream_iterator出力ストリーム書き込みデータ
    istream_iterator<int> int_it(cin); // cin  int
    istream_iterator<int> eof; //     
    vector<int> vec(int_it,eof);
    
    vector<int>::iterator myiter;
    for(myiter = vec.begin();myiter!=vec.end();myiter++)
    {
        cout << *myiter << endl;
    }

    注意:eofは空の反復器として定義され、ストリームにバインドされた反復器の場合、関連するストリームがファイルの末尾またはIOエラーに遭遇すると、反復器の値は末尾の反復器と等しくなります.
    //     
    const char *str = {"hello"};
    ostream_iterator<char> out_iter(cout,"
    "
    ); for(int i = 0;i<5;i++) { out_iter = str[i]; }

    3.3、逆反復器逆反復器は、容器内で末尾要素から先頭要素へ逆方向に移動する反復器である.逆反復器での漸減操作の意味は転倒する.逆反復器(++it)を1つ増やすと、前の要素に移動します.逆反復器を減算すると、要素に移動します.
    //     
    int arr[] = {1,2,3,4,5,6,7};
    size_t size = sizeof(arr)/sizeof(int);
    vector<int> vet_int(arr,arr+size);
    vector<int>::reverse_iterator iter;
    for(iter = vet_int.rbegin();iter!=vet_int.rend();iter++)
    {
        cout << *iter << endl;
    }

    4、汎用アルゴリズム構造
    4.1、5種類の反復器アルゴリズムに要求される反復器操作は5つの反復器カテゴリに分けることができる
  • 入力反復器
  • 出力反復器
  • 前方反復器
  • 双方向反復器
  • ランダムアクセス反復器
  • 第2のアルゴリズム分類方式は、シーケンス内の要素を読み書きまたは並べ替えるかどうかである.
    4.2、アルゴリズムパラメトリックモード大多数のアルゴリズムは以下の4の形式を有する
    //alg    
    alg(beg,end,other args);
    alg(beg,end,dest,other args);
    alg(beg,end,beg2,other args);
    alg(beg,end,beg2,end2,other args);

    4.3、アルゴリズム命名規範一部のアルゴリズムはリロード形式で述語を伝達する
    unique(beg,end);//  ==       
    unique(beg,end,compare);//  compare  

    _ifバージョンのアルゴリズムが要素値を受け入れるアルゴリズムには、通常、要素の代わりに述語を受け入れる同名のバージョンがあります.
    find(beg,end,val);//     val        
    find(beg,end,pred);//      pred     
    //           

    コピーと非コピーの区別
    reverse(beg,end);//   ,   
    reverse_copy(beg,end,dest);//     dest

    5、特定容器のアルゴリズム
    list, forward_Listは独自のsort,merge,remove,reverse,uniqueを定義した.汎用バージョンではランダムな反復器が必要なためlistとforwarには使用できません.list.
    リストとforward_の場合listは、汎用アルゴリズムではなくメンバー関数バージョンのアルゴリズムを優先的に使用する必要があります.