C++基礎知識面接必須、復習詳細(6)(容器、lambda関数)


C++基礎知識面接必須、復習詳細(6)
一般的な順序コンテナ
シーケンスコンテナタイプ
特長
vector
可変サイズの配列.高速ランダムアクセスをサポートします.末尾以外の場所で要素を挿入または削除するコストが高い
list
双方向チェーン・テーブル双方向シーケンスアクセスをサポートします.任意の場所での挿入削除は効率的で、高速アクセスはサポートされていません.
forward_list
一方向チェーン・テーブルワンウェイ・シーケンス・アクセスをサポートし、任意の場所に挿入して削除する効率が高い.
string
可変サイズの保存文字のコンテナ.高速ランダムアクセスをサポートします.末尾挿入削除速度が速い
array
固定サイズ配列.高速ランダムアクセスをサポートします.要素を追加または削除できません
deque
両端キュー.高速ランダムアクセスをサポートし、ヘッダーと末尾の挿入が速い.
  • は通常vectorを使用するが、他の容器
  • を選択するより良い理由がない限り、
  • プログラムがコンテナの間に削除を挿入する必要がある場合はlistまたはforward_を使用します.List効率が高い
  • プログラムが要素にランダムにアクセスする必要がある場合、vectorまたはdequeが好ましい
  • を使用する.
  • 反復器の範囲:[begin,end],すなわちbeginは最初の要素を表し,endは最後の要素の後の要素
  • である.
  • vectorの初期化:vectorは例
    vector<int> a; //      
    vector<int> a(10); //   size 10 vector
    vector<int> a(10,1); //10   ,     1
    vector<int> a{
           1,2,3,4,5}; //       
    
  • である.
  • arrayの初期化
    array<int,40> a; //   40 int  
    array<int,10> b={
           1}; //      1,   0
    //            ,  array  ,         
    array<int,10> c={
           0,1,2,3,4,5,6,7,8,9};
    array<int,10> d=c;
    
  • vectorオブジェクトがどのように成長するか
  • vectorは高速ランダムアクセス要素をサポートするため、要素を連続的に記憶し、容量の動的変更
  • をサポートする必要がある.
  • vector実装時に記録される2つのサイズ:sizeとcapacity sizeはすでに保存されている要素の数であり、capacityは新しいメモリ空間を割り当てない前提で最大収容可能な要素の数
       vector<int> f(5,1);
       cout << f.size()<<' '<<f.capacity()<<' ';   // 5,5
       f.push_back(1);
       cout << f.size() << ' ' << f.capacity() << ' '; //6 10
    
  • である.
  • Vectorは連続した配列で要素を格納し、集合がいっぱいになったら、新しいデータを追加するときは、より大きなメモリを割り当て、元のデータをコピーし、前のメモリを解放し、新しい要素
  • を挿入する.
  • はコンパイラによって実現される拡張方式が異なり、VS 2015では1.5倍、GCCでは2倍で拡張される.
  • の拡張倍数は実際には時間と空間のバランスであり、倍数が大きいと空間の浪費が深刻になり、倍数が小さいと頻繁な拡張を招く可能性がある.

  • stringのいくつかの方法
  • s.substr(pos,n)は文字列を返し、s中のposから始まるn文字列のコピー
  • を返す.
  • s.insert(pos,args)posの前にargsが作成した文字を挿入します.posは下付きまたは反復器
  • です.
  • s.find(s 1)sでs 1を検索し、最初の一致位置を返す下付きラベルがある場合はnpos
  • を返します.
  • s.compare(s 1)は、2つの文字列を比較し、sがs 1に等しいか、大きいか、または小さいかを判断し、0、正数または負の
  • を返す.
  • to_string(T a)はaをstringタイプに変換して返し、通常は数値タイプ
  • に変換する.
    コンテナアダプタ
    コンテナアダプタ名
    特長
    stack
    先入後出.ヘッダファイルtop()はスタック上部の要素push()を返し、要素pop()を追加して要素を削除します.
    queue
    先入先出.ヘッダファイルfront()戻りキューヘッダback()戻りキュー末尾要素push()要素pop()削除要素
    priority_queue
    優先順位付きキュー.設定された優先度ルールに基づいてキューのソートを行います.ヘッダファイルのデフォルトは、最大スタックpush()要素pop()削除要素です.
    priority_queue<Type, Container, Functional>
    //
    priority_queue <int,vector<int>,greater<int> > q;  //   
    priority_queue <int,vector<int>,less<int> > q;  //   
    

    よく使われる汎用アルゴリズム
  • find(vec.cbegin(),vec.cend()、val)valがvecに現れる場合、最初に現れる位置を返し、そうでない場合vecを返す.end()
  • accumulate(vec.cbegin(),vec.cend()、val)はvecの要素の和を返し、valはsumの初期値
  • である.
  • fill(vec.begin(),vec.end(),val)各要素をval
  • として記入する
  • sort(vec.begin(),vec.end(),cmp)ソートvec,cmp
  • を書き換えることができる
    Lambda式
  • C++11のLambda式は、匿名の関数オブジェクトを定義して作成するために使用され、プログラミング作業を簡略化する
  • lambda式はalgorithmライブラリのいくつかの汎用関数のパラメータ
  • によく用いられる.
  • lambdaの構文:
    [capture list] (parameter list)-> return type{
           function body}
    //capture list:    	 lambda              
    //paremeter list:    
    //return type:    
    //function body:   
    
  • は、パラメータリストおよび戻りタイプを無視することができるが、キャプチャリストおよび関数体
  • を常に含む必要がある.
  • lambda関数を書いてsortを大きいから小さいまでソート
        vector<int> nums{
           1,3,2,5,4};
        sort(nums.begin(), nums.end(), [](int a1,int a2) {
            return a1 > a2; });
        for(auto &i:nums)
            cout << i << ' ';
    	//5,4,3,2,1
    
  • を呼び出す
  • lambda関数をfor_として使用eachのパラメータ実行動作
        vector<int> nums{
           1,3,2,5,4};
        sort(nums.begin(), nums.end(), [](int &a1,int &a2) {
            return a1 > a2; });
        for_each(nums.begin(), nums.end(), [](int &a) {
            cout << a << ' '; });
    
  • は、lambda関数の値取得および参照取得
    //---------------    ----------- 
     	int a = 1;
        auto f2 = [&a] {
            return a; };
        a = 0;
        auto j = f2();
        cout << j << endl;   //   0,     a          
    //----------------   -------------
        int a = 1;
        auto f2 = [a] {
            return a; };
        a = 0;
        auto j = f2();
        cout << j << endl;   //   1, a  0            ,a       
    
    に注意するので、lambda関数でローカル変数の値を変更する場合は、参照取得
  • を使用する.
  • は、取得リストの値を=に設定することによって、その関数に表示されるすべてのローカル変数を取得することができる.取得カテゴリの値を&に設定すると、すべての関数で表示されるローカル変数
  • が参照されます.
  • デフォルトでは、1つのlambdaボディにreturn以外の文が含まれている場合、コンパイラはlambdaが空の
    //      
    [](int i){
           return i<0?-i:i;};
    [](int i)->int{
           if(i<0) return -i;else return i;}; //      ->int
    
  • に戻ると考えています.