C++汎用アルゴリズム
10803 ワード
1、汎用アルゴリズムの初期
標準ライブラリアルゴリズムは、少数の例外を除いて、1つの範囲内の要素を操作します.この範囲を「入力範囲」と呼び、処理する最初の要素と最後の要素の後の位置の反復器を表す前の2つのパラメータを常に使用します.
1.1.読み取り専用アルゴリズムは入力範囲内の要素のみを読み取り、要素を変更しない
読み取り専用で要素を変更しないアルゴリズムでは、通常cbegin()、cend()が使用されます.
2つのシーケンスを操作するアルゴリズム
1.2.ライトコンテナ要素アルゴリズムは、コンテナ操作を実行しないので、コンテナサイズを変更することはできません.
コピーアルゴリズム
1.3、並べ替えアルゴリズム
2、カスタム操作
2.1、アルゴリズムに関数を渡す
2.2、lambda式
1つのlambda式は、呼び出し可能なコードユニットを表す.名前のないインライン関数として理解できます.
[capture list]->return type{function bodt}[キャプチャリスト]lambdaが存在する関数で定義されたローカル変数のリスト(通常は空)(パラメータリスト)パラメータリストreturn type戻りタイプfunction body関数体
暗黙的なキャプチャ
ブレンドキャプチャ方式を使用する場合、キャプチャ方式は同じではありません.すなわち、暗黙的なキャプチャが値キャプチャである場合、明示的なキャプチャは参照キャプチャである必要があります.
可変lambda
Lambda戻りタイプの指定
2.3、パラメータバインド
bind関数
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出力ストリーム書き込みデータ
注意:eofは空の反復器として定義され、ストリームにバインドされた反復器の場合、関連するストリームがファイルの末尾またはIOエラーに遭遇すると、反復器の値は末尾の反復器と等しくなります.
3.3、逆反復器逆反復器は、容器内で末尾要素から先頭要素へ逆方向に移動する反復器である.逆反復器での漸減操作の意味は転倒する.逆反復器(++it)を1つ増やすと、前の要素に移動します.逆反復器を減算すると、要素に移動します.
4、汎用アルゴリズム構造
4.1、5種類の反復器アルゴリズムに要求される反復器操作は5つの反復器カテゴリに分けることができる入力反復器 出力反復器 前方反復器 双方向反復器 ランダムアクセス反復器 第2のアルゴリズム分類方式は、シーケンス内の要素を読み書きまたは並べ替えるかどうかである.
4.2、アルゴリズムパラメトリックモード大多数のアルゴリズムは以下の4の形式を有する
4.3、アルゴリズム命名規範一部のアルゴリズムはリロード形式で述語を伝達する
_ifバージョンのアルゴリズムが要素値を受け入れるアルゴリズムには、通常、要素の代わりに述語を受け入れる同名のバージョンがあります.
コピーと非コピーの区別
5、特定容器のアルゴリズム
list, forward_Listは独自のsort,merge,remove,reverse,uniqueを定義した.汎用バージョンではランダムな反復器が必要なためlistとforwarには使用できません.list.
リストとforward_の場合listは、汎用アルゴリズムではなくメンバー関数バージョンのアルゴリズムを優先的に使用する必要があります.
標準ライブラリアルゴリズムは、少数の例外を除いて、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、反復器
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つの反復器カテゴリに分けることができる
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は、汎用アルゴリズムではなくメンバー関数バージョンのアルゴリズムを優先的に使用する必要があります.