vectorコンテナ

配列を動的に調節するにはvectorを使用します。vector必要な分だけのメモリを確保することが可能となります。ここではvectorの使い方を紹介します。

前準備

まず、使う前に

#include <vector>;
using namespace std;

で<vector>をインクルードする必要があります。また、STLはstdという名前空間で定義されているので、stdも取り込みましょう。もし、using namespace std;がないと、vectorを使用するたびにstd::をつける必要があります。

定義と要素の内容

次に、ベクタを定義する際は

vector<int> x(10);

というようにします。こうすることで、int型で要素数10のベクタxが定義されます。ベクタの内容を初期化したい場合は

vector<int> x(10,1);

とすればOKです。この場合は、ベクタxは1に初期化されます。要素の内容は

x[要素番号]

で設定できます。配列と同じです。例えば

int i=x[0];

のように使います。通常の配列と同様に、要素番号は0から始まるので注意しましょう。

ベクタの命令

要素数を返す命令size

ベクタの要素数を知りたい場合は、「size」を使います。

size_type size() const;

使用例は以下の通りです。

vector<int> x(10);
int i=x.size();
cout<<i<<endl;

これで10が表示されます。

要素の追加と削除push_backとpop_back

ベクタでは要素数を増やしたり減らしたりできます。要素数を増やす場合はpush_back、減らす場合はpop_backを使用します。使用例を以下にのせます。

vector<int> x(10,1);
x.push_back(11);
cout<<x[10]<<endl;
x.pop_back();

この結果、「11」が表示されます。

pop_backを要素数が0の場合に使用すると、vectorのサイズがおかしくなります。そこで、vectorのサイズが0でないことを確認してpop_backを使用するのが安全です。vectorのサイズをsizeで調べてもいいのですが、emptyという命令を使ったほうが効率的です。

if(!x.empty())x.pop_back();

という具合にしようしましょう。emptyはベクタが空ならtrueを返します。

配列情報を取り出す

vectorの配列情報を取り出す際は、data()メソッドを使用します。dataにより配列のアドレスを取得できます。

反復子

配列といったらポインタを使いたくなります。ベクタでは、反復子(iterator)を利用してアドレスにアクセスします。C++のポインタのようなものが反復子だと思ってください。

反復子を使って要素にアクセスする

まず、反復子の定義は

vector::iterator p;

とします。そして、ベクタの先頭ポインタを取得したい場合は

vector<int> x(10);
vector<int>::iterator p;
int i;
p=x.begin();
while(p != x.end()){
   *p=i;
   p++;
   i++;
}

というように、begin()を使用します。そして、end()を利用すれば、最終要素の次のポインタを取得できます。最終要素はend()-1となるので注意しましょう。それから、*pでアドレスpの値を返します。

挿入と削除

要素の間に新たに要素を挿入したり削除したい場合があります。例えば、

1,2,3,4,5

の2と3の間に0を4つ挿入して

1,2,0,0,0,0,3,4,5

としたり、3と4を消して

1,2,5

とする場合です。いかに使用例をのせます。

int main(void){
vector<int> x(10,1);
vector<int>::iterator p;

//配列を表示
for(int i=0;i<x.size();i++)cout<<x[i]<<" "; cout<<"\n\n";

//0を4つ挿入する
p=x.begin();
p+=2;
x.insert(p,4,0);

//配列を表示
for(int i=0;i<x.size();i++)cout<<x[i]<<" "; cout<<"\n\n";

//4つ消す
p=x.begin();
p+=2;
x.erase(p,p+4);

//配列を表示
for(int i=0;i<x.size();i++)cout<<x[i]<<" "; cout<<"\n\n";

return 0;
}

実行すると以下の様な結果になります。

1 1 1 1 1 1 1 1 1 1

1 1 0 0 0 0 1 1 1 1 1 1 1 1

1 1 1 1 1 1 1 1 1 1

「0」が4つ挿入され、4つ消されます。

命令のまとめ

いかにvectorの命令をまとめます。

命令 説明
size_type size() const; ベクタの要素数を返します。
bool empty() const; ベクタに要素がない場合にtrueを返します。
void push_back(const T &val); valと同じ値の要素をベクタの最後に追加します。
void pop_back(); ベクタの最後の要素を削除します。
iterator begin(); ベクタの先頭を指す反復子を返します。
iterator end(); ベクタの最後の要素の次の反復子を返します。
iterator erase(iterator i); iが示す要素を削除して、削除された要素の次の要素の反復子を返します。
iterator erase(iterator start,iterator end); startからendまでの範囲の要素を削除して、削除された最後の要素の次の要素を示す反復子を返します。
iterator insert(iterator i, const T &val); iが示す要素の直前にvalを挿入して、その要素を示す反復子を返します。
void insert(iterator i, size_type num, const T &val); iが示す要素の直前にvalをnum個挿入します。

注意事項

vectorは動的にメモリを確保します。当然ですが、メモリの確保に失敗したらエラーになります。ですから、メモリを確保する際はtryとcatchで囲んでおいて、エラー処理を行なってください。

はじめの宣言の部分や、push_backでメモリを確保できないとエラーとなります。それと、メモリの解法についてはデコンストラクタが呼ばれるタイミングになります。

著者:安井 真人(やすい まさと)