C++primer第五版個人ノート第九章順序容器

5224 ワード

9.1シーケンスコンテナの概要
  • シーケンスコンテナタイプ、vector可変サイズ配列、高速ランダムアクセスをサポートし、末尾以外の位置で要素を挿入または削除するのは遅い
  • deque両端キューで、高速ランダムアクセスをサポートします.ヘッダーと末尾の位置での挿入/削除速度が速い
  • list双方向チェーンテーブルは、双方向シーケンスアクセスのみをサポートし、list内の任意の場所での挿入/削除操作速度は
  • 速い.
  • forward_List一方向チェーンテーブルは、一方向シーケンスアクセスのみをサポートし、チェーンテーブルの任意の場所で挿入/削除操作を行うのは速い
  • array固定サイズ配列.要素
  • を追加または削除できない高速ランダムアクセスをサポート
  • stringはvectorに似たコンテナですが、文字の保存に特化しています.ランダムアクセスが速く、末尾に挿入、削除速度が速い
  • forward_Listとarrayは新しいC++標準が増加したタイプです.新しい標準ライブラリのコンテナは古いバージョンよりずっと速いです.
  • いくつかの操作はすべてのコンテナタイプに対して使用され、295ページ
  • を参照してください.
  • 無秩序関連コンテナは、関係演算子<,<=,>,>=をサポートしません.シーケンスコンテナの構造関数のみがサイズパラメータを受け入れることができます.
  • forward_Listは減算演算子をサポートしていません--
  • あるコンテナが別のコンテナのコピーを初期化する場合、両方のコンテナのコンテナタイプと要素タイプは同じでなければならない.しかし、反復器begin()、end()で初期化する場合は不要であり、反復器要素が変換された容器の要素に変換できればよい.
  • arrayと内蔵配列の違いは、arrayがコピーまたはオブジェクト付与操作を行うことができ、内蔵配列は
    array digits={1,2,3,4,5,6,7};
    array cpy = digits;         //  ,           
    
    int digs[7]={1,2,3,4,5,6,7};
    int cpy[7] = digs;                 //  ,            
    ではいけないことである.右演算オブジェクトのサイズが左演算オブジェクトのサイズと異なる可能性があるため、arrayタイプはassignをサポートせず、カッコで囲まれた値リストで付与することも許されない(コンパイラによっては実行可能).
    int main()
    {
    	array a1 = { 0,1,2,3,4,5,6,7,8,9 };
    	array a2 = { 0 };
    	// a1.assign(a2.begin(),a2.end());             //    
    	a1 = { 0 };                                    //        ,   vs2019       
    	for (auto i : a1)
    	{
    		cout << i << " ";
    	}
    
    	return 0;
    }
     
  • swapの動作速度は、要素をコピーするのではなく、2つのコンテナ内部のデータ構造を交換することにある.swapの2つのarrayは本当に彼らの要素を交換します.したがって、swap操作後、元のコンテナの反復器が指す要素は変わらないが、arrayは要素を交換し、元のコンテナ反復器が指す要素はswap後の対応位置の値に変更され、コードは以下の
    int main()
    {
    	array a1 = { 0,1,2,3,4,5,6,7,8,9 };
    	array a2 = { 0 };
    	array::iterator iter = a1.begin() + 1;
    	cout << *iter << endl;						//  1
    	swap(a1, a2);	
    	cout << *iter << endl;						//  0
    	vectorvec1 = { 1,2,3,4 };
    	vectorvec2(vec1.begin()+1, vec1.end());
    	vector::iterator iter1 = vec1.begin() + 1;
    	cout << *iter1 << endl;						//  2
    	swap(vec1, vec2);
    	cout << *iter1 << endl;						//  2
    
    	return 0;
    }
  • である.
  • 練習9.14コード、vs 2019実行成功
    int main()
    {
    	list li = { "hello","myname" };    //     const char*   
    	vector vec(li.cbegin(), li.cend());
    	for (auto str:vec)
    	{
    		cout << str << endl;
    	}
    
    	return 0;
    }
  • 9.3手順容器操作
  • 要素をvectorに挿入すると、stringまたはdequeが要素を挿入すると、コンテナを指すすべての反復器、参照、およびポインタが無効になります. 
  • はinsert(iter,val)を介してvector/deque/string内の任意の位置に要素を挿入することができるが、これには時間がかかる.
  • emplace_front/emplace/emplace_backはそれぞれpush_に対応front/insert/push_back関数は、emplace操作がパラメータをコンテナに渡し、コンテナから要素の構造関数を呼び出し、コンテナ内の要素がカスタムクラスの場合、パラメータを直接入力することができ、例えば
    vector c;
    c.emplace_back("9812-33234",25,15.99) //       sales_data    
    c.push_back(sales_data("9812-33234",25,15.99)) //    sales_data  ,    
    c.push_back("9812-33234",25,15.99) //    
    emplace関数がコンテナ内で要素を直接構築する.emplace関数に渡されるパラメータは、要素タイプの構造関数と一致する必要があります.
  • コンテナで要素にアクセスするメンバー関数(front,back,下付き,at)は、コンテナがconstオブジェクトである場合、戻り値がconstの参照である参照を返します.   
  • dequeの先頭位置以外の要素を削除すると、すべての反復器、参照、ポインタが無効になります.vectorまたはstringで点を削除した後の位置を指す反復器、参照、ポインタは無効になります.
  • end()から返される反復器を保存しないでください.操作によって容器のサイズが変更されると、元の反復器、参照、ポインタが失効し、予想外の結果をもたらす可能性があります.
  • capacity()とsize()の違いは、sizeが保存した要素の数を返し、capacityは新しいメモリ空間を割り当てずに最大保存できる要素を返すことである.

  •  
    9.5追加string操作
  • assignとappend関数はstringのどの部分を置き換えるかを指定する必要はありません.assignはstringのすべての内容を常に置き換え、appendは常に新しい文字をstringの末尾に追加します.
  • 9.5.2節練習、findとreplaceを使用するのはinsertとeraseより明らかに簡潔です
    
    //    replace    
    void findstr(string& s, string& oldVal, string& newVal)
    {
    	string::size_type pos = 0;
    	while ((pos=s.find(oldVal,pos)) != -1)
    	{
    		s.replace(pos, oldVal.size(), newVal);
    		pos = pos + newVal.size();
    	}
    }
    
    //   ,insert erase  ,       
    void findstr(string& s, string& oldVal,const string& newVal)
    {
    	for (auto iter = s.begin(); iter != s.end(); ++iter)
    	{
    		if (*iter == oldVal[0])
    		{
    			int flag = 1;
    			for (int i = 0; i < oldVal.size(); ++i)
    			{
    				if ((*(iter + i) != oldVal[i]) || (iter + i) == s.end())
    				{
    					flag = 0; break;
    				}
    			}
    			if (flag)
    			{
    				iter = s.erase(iter, iter + oldVal.size());
    				iter = s.insert(iter, newVal.begin(), newVal.end()); //       ,     iter       
    				iter = iter + newVal.size() - 1;
    				if (iter >= s.end()) break;
    			}
    			
    		}
    	}
    }
    
    // compare    
    void findstr(string& s, string& oldVal,const string& newVal)
    {
    	string::size_type pos = 0;
    	string::size_type osize = oldVal.size(), nsize=newVal.size();
    	for (; pos < s.size(); ++pos)
    	{
    		if (s.compare(pos, osize, oldVal) == 0)
    		{
    			s.replace(pos, osize, newVal);
    			pos += newVal.size();
    		}
    	}
    }
    
    
  • findの使い方が多いのは3パラメータ、iterator、string_tofind, pos 
  • 整数、浮動小数点数を文字に変換する最も簡単な方法はto_string(int i)関数、stringの操作方法は多すぎて、繰り返し帰って本を読むことができます
  •