C++には、長さが変えられる配列のvectorがあります。この記事では、vector型について、
- vectorとは
- vectorの宣言方法
- ループを使ったvector型の要素へのアクセス
という基本的な内容から、vectorの各種メンバ関数の使い方や、algorithmライブラリを使ってvectorを操作する方法などの応用的な使い方についても解説していきます。
vector型とは
C++で配列の長さを変えることができる配列を扱うために、vectorというクラスがあります。また、この長さを変えることができる配列のことを可変長配列といいます。
vectorの宣言方法
vector型の変数を宣言するためには、vectorというライブラリをインクルードします。vectorは以下のように宣言します。
std::vector<型名> 変数名;
要素を先に確保して、さらに全ての要素を同じ値で初期化したいときには、
std::vector<型名> 変数名(要素数); std::vector<型名> 変数名(要素数,値);
C++11以降は、配列のように直接値を入れることができます。
std::vector<型名> 変数名= {要素1,要素2};
また、vectorで二次元以上の配列を宣言するには、
std::vector<std::vector<型名> > 変数名;
ただ、「> >」と、間に空白を入れないとエラーになる可能性があります。先ほどと同じように、初期化をしたい場合は、
std::vector<std::vector<型名> > 変数名(要素数,vector<型名>(要素数); std::vector<std::vector<型名> > 変数名(要素数,vector<型名>(要素数,値); std::vector<std::vector<型名> > 変数名{{要素1,要素2},{要素} };
ループを使ったvector型の要素へのアクセス
vector型の要素をループを使って一つづつ要素を取得するには、いくつか方法があります。
for文と添字を使ってvectorの要素を取得する
まず、配列のように、添字を使うには、以下のようになります。
#include <vector> #include <stdio.h> int main(void) { std::vector<int> vec{ 1, 2, 3 }; for (int i = 0; i < vec.size(); i++) printf("%d,", vec[i]); printf("\n"); return 0; }
実行結果:
1,2,3,
範囲for文を使ってvectorの全要素を取得する
C++11以降は、範囲for文というものを使うことができます。範囲for文は以下のように使います。
for ( auto& 要素名 : vector) { // 処理 }
このautoというのは、型推論といい、型を自動で考えてくれます。これを使うと以下のように、前のコードをもう少し簡潔に書くことができます。
#include <vector> #include <stdio.h> int main(void) { std::vector<int> vec{ 1, 2, 3 }; for (auto &num:vec) printf("%d,", num); printf("\n"); return 0; }
実行結果:
1,2,3,
イテレータの使い方と取得方法
vectorには、iterator(イテレータ)というポインタのように使うことができるものが用意されています。イテレータの宣言方法は、以下のようになります。
vector<型名>::iterator イテレータ;
(※ ただ、型名が長く面倒なため、通常はauto型とかくことの方が多いです。)
これを使うと、例えば
vector<int>::iterator itr;
というイテレータに対して、
*itr;
でイテレータが指す要素を参照・変更することができ、
++itr; --itr;
で次・前の要素に移動することができます。begin関数は一番初めの要素への、end関数は一番後ろの要素の次へのイテレータを示します。これらを使うことで、vectorの全要素を取得することができます。
#include <vector> #include <stdio.h> int main(void) { std::vector<int> vec{ 1, 2, 3 }; for (auto it = vec.begin(); it != vec.end(); ++it) printf("%d,", *it); printf("\n"); return 0; }
実行結果:
1,2,3,
vectorの各種メンバ関数の使い方
push_back、emplace_backで末尾に要素を追加する
push_back・emplace_back関数を使うと一番後ろ、末尾に要素を追加することができます。
ただし、emplace_back関数は、C++11以降から使うことができます。両者は使い方としては同じですが、内部の動作が違い、emplace_backの方が高速に動作する場合があります。
#include <vector> #include <stdio.h> int main(void) { std::vector<int> vec{ 1, 2, 3 }; printf("要素を追加する前:\n"); for (auto it = vec.begin(); it != vec.end(); ++it) printf("%d,", *it); printf("\n\n"); vec.push_back(4); vec.emplace_back(5); printf("要素を追加した後:\n"); for (auto it = vec.begin(); it != vec.end(); ++it) printf("%d,", *it); printf("\n"); return 0; }
実行結果:
要素を追加する前: 1,2,3, 要素を追加した後: 1,2,3,4,5,
insert、emplaceで要素を挿入、連結する
insert・emplace関数を使うと、途中に要素を挿入することができます。この2つは使い方は同じですが、内部の動きがすこし違います。
vector.insert(イテレータ,値);
のように使います。
#include <vector> #include <stdio.h> int main(void) { std::vector<int> vec{ 1, 2, 3 }; printf("要素を追加する前:\n"); for (auto it = vec.begin(); it != vec.end(); ++it) printf("%d,", *it); printf("\n"); vec.insert(vec.begin() + 1, 4); vec.insert(vec.begin() + 2, 6); printf("要素を追加した後:\n"); for (auto it = vec.begin(); it != vec.end(); ++it) printf("%d,", *it); printf("\n"); return 0; }
実行結果:
要素を追加する前: 1,2,3, 要素を追加した後: 1,4,6,2,3,
pop_backで末尾の要素を削除する
pop_back関数を使うことで、末尾の要素を削除することができます。
#include <vector> #include <stdio.h> int main(void) { std::vector<int> vec{ 1, 2, 3 }; printf("削除する前:\n"); for (auto it = vec.begin(); it != vec.end(); ++it) printf("%d,", *it); printf("\n\n"); vec.pop_back(); printf("削除した後:\n"); for (auto it = vec.begin(); it != vec.end(); ++it) printf("%d,", *it); printf("\n"); return 0; }
実行結果:
削除する前: 1,2,3, 削除した後: 1,2,
eraseで要素を削除する
erase関数を使うことで、要素を削除することができます。
#include <vector> #include <stdio.h> int main(void) { std::vector<int> vec{ 1, 2, 3, 4, 5, 6 }; printf("削除する前:\n"); for (auto it = vec.begin(); it != vec.end(); ++it) printf("%d,", *it); printf("\n\n"); vec.erase(vec.begin() + 2); printf("削除した後:\n"); for (auto it = vec.begin(); it != vec.end(); ++it) printf("%d,", *it); printf("\n"); return 0; }
実行結果:
削除する前: 1,2,3,4,5,6, 削除した後: 1,2,4,5,6,
sizeで要素数を取得する
size関数を使って、現在使われている要素の数を調べることができます。
#include <vector> #include <stdio.h> int main(void) { std::vector<int> vec{ 1, 2, 3, 4, 5, 6 }; printf("要素数:%lun", vec.size()); return 0; }
実行結果:
要素数:6
algorithmライブラリを使ってvectorを操作する方法
algorithmというライブラリには使いやすい関数がいくつもあります。
findで要素を検索する
find関数を使うと、vectorの要素の中から指定された値を探すことができます。find関数は、範囲を示すイテレータを受け取って、最初に見つかったところへのイテレータを返します。見つからなかった場合は、変数名.end()を返します。
#include <stdio.h> #include <vector> #include <algorithm> int main(void) { std::vector<int> vec{ 1, 2, 3, 4, 5, 6 }; printf("要素:\n"); for (auto it = vec.begin(); it != vec.end(); ++it) printf("%d,", *it); printf("\n\n"); int num = 5; auto it = std::find(vec.begin(), vec.end(), num); if (it != vec.end()) { printf("%dは見つかりました。\n", num); }else { printf("%dは見つかりませんでした。\n", num); } return 0; }
実行結果:
要素: 1,2,3,4,5,6, 5は見つかりました。
sortで要素をソートする
sort関数を使うことで、要素を順番に並び替えることができます。
#include <stdio.h> #include <vector> #include <algorithm> int main(void) { std::vector<int> vec{ 1, 5, 7, 2, 8, 4 }; printf("sortする前の要素:\n"); for (auto it = vec.begin(); it != vec.end(); ++it) printf("%d,", *it); printf("\n\n"); std::sort(vec.begin(), vec.end()); printf("sortした後の要素:\n"); for (auto it = vec.begin(); it != vec.end(); ++it) printf("%d,", *it); printf("\n"); return 0; }
実行結果:
sortする前の要素: 1,5,7,2,8,4, sortした後の要素: 1,2,4,5,7,8,
まとめ
いかがだったでしょうか?今回はvectorを使って長さが変えることができる配列をつくる方法などを解説しました。配列の長さがわからないときなどに使用してください。
もし、vectorの使い方を忘れてしまったらこの記事を確認してください。