C++のvectorコンテナオブジェクト学習ノート

7567 ワード

C++の配列は穴があいていますが、Pythonのリストのようなデータ型はありますか?似たようなのがvector!vectorは同じタイプのオブジェクトの集合であり、各オブジェクトには対応する整数インデックス値があります.stringオブジェクトと同様に、標準ライブラリはストレージ要素に関連するメモリを管理します.私たちがvectorをコンテナと呼ぶのは、他のオブジェクトを含むことができるからです.1つのコンテナ内のすべてのオブジェクトは同じタイプでなければなりません.
vectorオブジェクトの定義と初期化
同様に、使用前に、インポートヘッダファイルincludeはusing宣言:using std::vector;
vectorはクラステンプレート(class template)です.テンプレートを使用して、クラス定義または関数定義を作成し、複数の異なるデータ型に使用します.したがって、stringオブジェクトを保存するvector、またはint値を保存するvector、またはSales_itemsオブジェクトなどのカスタムクラスタイプオブジェクトを保存するvectorを定義できます.
クラステンプレートから生成されたオブジェクトのタイプを宣言するには、テンプレートに応じて情報の種類を追加する必要があります.vectorの例では、vectorが保存するオブジェクトのタイプを説明する必要があります.タイプをクラステンプレート名の後ろのカッコに置くことで、タイプを指定します.
vector v1;
保存タイプはTオブジェクトです.デフォルトのコンストラクション関数v 1は空です.
vector v2(v1);
v 2はv 1のコピーです.
vector v3(n, i);
v 3には、n個の値iの要素が含まれます.
vector v4(n);
v 4は、値初期化要素のn個のコピーを含む.
【注意:1、空でないvectorオブジェクトを作成するには、初期化要素の値を指定する必要があります.2、あるvectorオブジェクトを別のvectorオブジェクトにコピーすると、新しくコピーしたvectorの各要素は元のvectorsの対応する要素のコピーに初期化されます.ただし、この2つのvectorオブジェクトは同じ要素タイプを保存する必要があります.3、要素の数と要素値を使用できますvectorオブジェクトを初期化します.コンストラクション関数は要素の個数でvectorオブジェクトが要素を保存することを決定します
個の数、要素値は各要素の初期値を指定します.
vectorオブジェクトの動的成長:
vectorオブジェクト(および他の標準ライブラリコンテナオブジェクト)の重要なプロパティは、実行時に効率的に要素を追加できることです.
【注意:なぜなら
vectorの増加効率が高い
を選択します.値の初期化:
エレメントの初期化式が指定されていない場合、標準ライブラリはvectorに格納されているエレメントのデータ型に応じて、エレメントの初期値を独自に提供します.
int型データの場合、標準ライブラリは0値で要素初期化式を作成します.
vectorがstringなどの構造関数を含むクラスタイプの要素を保存している場合、標準ライブラリはこのタイプのデフォルトの構造関数で要素初期化式を作成します.
要素タイプは、コンストラクション関数が定義されていないクラスタイプである可能性があります.この場合、標準ライブラリは、各メンバーが値初期化された初期値付きオブジェクトを生成します.

#include 
#include 
#include 

int main()
{
 std::vector a;
 std::vector b(a);
 std::vector c(10, 23);
 std::vector<:string> svec(10, "null");
 std::vector<:string> svec2(10, "hi!");
 std::vector<:string> svec3(10);
 return 0;
}


注意、=号はありません!vectorオブジェクトの操作方法
stringと似ています!のv.empty()
Returns true if v is empty; otherwise returns false vが空の場合はtrue、そうでない場合falseを返します.
.v.size()
Returns number of elements in vは、v内の要素の個数を返します.
【注意:1、対応するvectorクラスで定義されたsize_typeの値を返します.stringと似ています.2、size_typeタイプを使用する場合、そのタイプがどこで定義されているかを示す必要があります.vectorタイプには常に
vectorを含む要素タイプvector::size_type

v.push_back(t)

Adds element with value t to end of v  v           t    。     :

#include 
#include 
#include 
#include 

int main()
{
 // read words from the standard input and store them as elements in a vector
 std::string word;
 std::vector<:string> text; // empty vector
 while (std::cin >> word) 
 {
 text.push_back(word); // append word to text
 for(std::vector::size_type ix =0; ix != text.size(); ++ix)
  std::cout< 
 

結果:

Hello
Now text[0]is: Hello
world!
Now text[0]is: Hello
Now text[1]is: world!

注意:1、vectorオブジェクトを直接出力することはできません!リストとの差が大きすぎます...
2、下付き操作は既存の要素を変更することができる:例えば、前例、最後に:text[0]=「elements」を加えることができる;
3、もちろんlistと同じように、text[100]=「elements」はできないに違いない.Pythonでこのようにlistリターンを操作すると、C++でコンパイルしてもエラーは報告されず、自動的に終了します.【配列操作時にこれはあなたを殺すことができて、間違いを報告しないで、退出しません!もちろん、バッファがあふれて、ハッカーたちはとても好きです!】
4、動的成長のため、長さを先にテストするのではなく、サイクル中の動的テスト!さもなくばわけのわからないBUGが現れます!効率を心配する人はいますか?心配しないで!コストは小さい【インライン関数】.
v[n]
Returns element at position n in vは、vの位置nの要素を返します.
(1)v1 = v2[/code]
Replaces elements in v 1 by a copy of elements in v 2 v 1の要素をv 2の要素のコピーに置き換えます.
(2)v1 == v2[/code]
Returns true if v 1 and v 2 are equal v 1がv 2と等しい場合はtrueを返します.
(3)!=, and >=
Have their normal meaningsは、これらのオペレータが慣れている意味を維持します.
簡単な例です
vectorオブジェクトにテキストを読み込み、各単語はvectorの要素として格納されます.vectorオブジェクトの各単語を大文字に変換します.vectorオブジェクトで変換された要素を出力し、8単語ごとに1行出力します.
仮定テキストは:in the vector.transform each word into uppercase letters. Print the transformed elements from the vector, printing eight words to a line.

#include 
#include 
#include 

std::string deal_word(std::string word)
{
 std::string WORD; //       
 for(std::string::size_type ix =0; ix != word.size(); ++ix)
 {
 if (not ispunct(word[ix]))
 {
  WORD += toupper(word[ix]); //           
 }
 }
 return WORD;
}

int main()
{
 std::string word; //        
 std::vector<:string> text; // empty vector
 std::cout<> word and word != "INPUTOVER") // INPUTOVER         ,   ctrl + z     
 {
 word = deal_word(word); //     
 text.push_back(word); // append word to text
 }
 for(std::vector::size_type ix =0, j = 0; ix != text.size(); ++ix, ++j)
 {
 if (j==8) // 8     
 {
  std::cout<<:endl j="0;" std::cout="" return=""> 
 

結果:

Please input the text:
in the vector. transform each word into uppercase letters. Print the transformed elements from the vector, printing eight words to a line. INPUTOVER
IN THE VECTOR TRANSFORM EACH WORD INTO UPPERCASE 
LETTERS PRINT THE TRANSFORMED ELEMENTS FROM THE VECTOR 
PRINTING EIGHT WORDS TO A LINE


vector.resizeとvector.reserve
reserveはコンテナの予約スペースですが、本当に要素オブジェクトを作成するわけではありません.オブジェクトを作成する前に、コンテナ内の要素を参照することはできません.そのため、新しい要素を追加する場合はpush_back()/insert()関数.resizeはコンテナのサイズを変更し、オブジェクトを作成するため、この関数を呼び出すとコンテナ内のオブジェクトを参照できます.したがって、新しい要素を追加する場合はoperator[]オペレータを使用するか、反復器を使用して要素オブジェクトを参照します.さらに、2つの関数の形式には違いがあり、reserve関数の後のパラメータ、すなわち予め残された容器の空間が必要である.resize関数には2つのパラメータがあり、1つ目のパラメータはコンテナの新しいサイズであり、2つ目のパラメータはコンテナに追加する新しい要素であり、このパラメータが省略されると、要素オブジェクトのデフォルトの構造関数が呼び出されます.次の2つの関数の使用例を示します.

vector myVec;

myVec.reserve( 100 );  //         ,

       //      []    

for (int i = 0; i < 100; i++ )

...{

  myVec.push_back( i ); //        

}

myVec.resize( 102 );  //                    

myVec[100] = 1;   //       

myVec[101] = 2;


この2つのインタフェースに初めて接触すると混同されるかもしれませんが、インタフェースの名前は機能の絶好の説明であり、resizeはサイズを再割り当てし、reserveは一定の空間を残すことです.この2つのインタフェースには違いがあり、共通点もあります.以下、それらの詳細について分析します.resizeの意味を実現するために、resizeインタフェースは2つの保証を行った:1つは保証区間[0,new_size)の範囲内のデータが有効であり、下付きindexがこの区間内であればvector[indext]が合法である.二つ目は、保証区間[0,new_size)の範囲外のデータが無効であり、下付きindexが区間外であればvector[indext]が不正である.reserveはvectorの空間サイズ(capacity)がそのパラメータで指定されたサイズnに最小限に達することを保証するだけである.区間[0,n)の範囲内で、下付きがindexであればvector[index]というアクセスは合法的である可能性もあり、不法である可能性もあり、具体的な状況によって異なります.resizeインタフェースとreserveインタフェースの共通点は、vectorの空間サイズ(capacity)がパラメータで指定されたサイズに最小限に達することを保証することです.2つのインタフェースのソースコードはかなりシンプルなので、ここに貼り付けることができます.

void resize(size_type new_size) 
{ 
 resize(new_size, T()); 
}
void resize(size_type new_size, const T& x) 
{
 if (new_size < size()) 
  erase(begin() + new_size, end()); // erase         ,           
 else
  insert(end(), new_size - size(), x); //             ,          
}