C++のvectorを復習する
1. はじめに
C++のvectorは、可変長のデータを便利に取り扱えるため、非常に便利である。ここでは、vectorの使い方を簡単に記す。
2 vectorとは
2.1 固定長と可変長
配列の表現方法には、固定長と可変長がある。固定長とは、データサイズが固定であるため、実行時にサイズ変更することができない(例:int data[10])。
一方、可変長では、プログラム実行時にデータサイズを自由に変更できる(例:vecter、map、malloc)。
2.2 vectorとは
vectorとは、可変長データを取り扱うことができるデータ構造のことである。
2.2.1 メリット:操作が簡単
vectorを使用するメリットは、データの追加・修正などの操作が簡単にできることである。また、使用方法も従来の配列と同様のアクセスができる。
2.2.2 デメリット:再割り当てに時間がかかる
もちろんデメリットも存在する。例えば、vectorで予め確保した量を超えたサイズとなる場合は、再割り当てにオーバーヘッドがかかる。どうやらvectorは、メモリが不足する場合は、新しい場所にコピーをするようだ。そのため、速度的な問題は気にする必要がある。
2.3 vectorの使用例
下記にvectorの使用例を示す。
#include <iostream>
#include <vector>
int main()
{
//vector<int>型の可変長データを宣言
std::vector<int> vec;
//vectorに10を代入する
vec.push_back(10);
//vectorに100を代入する
vec.push_back(100);
//vectorの要素数を取得する
int size = vec.size();
//要素数分繰り返す
for (int i = 0; i < size; i++) {
//中身を表示する
std::cout << vec[i] << std::endl;
}
}
上記は、vectorの使用例を示したものである。下記に処理をまとめる。
(1) vector<int>型のデータのvecを宣言する
(2) vecに10と100の数値を代入する。
(3) vecの要素数を取得する
(4) vecの要素数分繰り返し、中身を表示する
このように、vectorでデータの操作が簡単に実施できる。
3. vectorの使用方法
ここでは、vectorの使用方法をまとめる。
3.1 ヘッダファイル
vectorでは、<vector>ヘッダをインクルードして使用する。
#include <vector>
3.2 vectorの宣言
vectorの宣言は、以下のように記述する。
//vectorの定義
std::vector<データ型> 変数名
データ型には、任意のデータ型(int, double, 構造体)などを入れることができる。実際の記述例は、以下である。
//int型の可変長データvecの宣言
std::vector<int> vec;
//double型の可変長データvecの宣言
std::vector<double> vec;
//構造体の可変長データvecの宣言
std::vector<DATA> vec;
宣言は見慣れないかもしれないが、簡単である。
3.3 データの追加
データを追加する方法を説明する。
3.3.1 push_back(末尾に追加)
データの末尾に追加するには、push_backを使用する。
std::vector<int> vec;
//10を代入する
vec.push_back(10);
std::vector<double> vec;
//10.4を代入する
vec.push_back(10.4);
上記の例は、push_backを使用して、データ型に合ったデータを追加する。
3.3.2 insert(任意の位置に追加)
任意の位置にデータを追加するには、insertを使用する。
//定義:
insert(イテータの位置, 値);
std::vector<int> vec = {1, 2, 3, 4, 5};
//3個目の位置に値6を挿入
vec.insert(vec.begin() + 2, 100);
insertの第一引数には、iteratorを渡す。ここでは、iteratorの先頭を表すbegin()を入れている。また、その2個先とするため、+2で3番目を設定している。
3.4 データの参照
データの参照は、普通の配列と変わらない。
std::vector<int> vec = {1, 2, 3, 4};
//0番目を表示する
std::cout << vec[0] << std::endl;
上記の例は、データの参照方法である。ここでは、0番地である1を表示している。例からわかる通り、固定長の配列と何ら変わりない。
3.5 データの要素数の取得
データの要素数を取得するには、sizeを使用する。
std::vector<int> vec = {1, 2, 3, 4};
//要素数を取得する
std::cout << vec.size() << std::endl;
上記のように記述することでvectorの要素数を取得することができる。
3.6 繰り返し
vectorの中身を繰り返す方法は以下の通りである。
3.6.1 sizeでループする
先ほどのsizeでループする例で考える。
std::vector vec = {1, 2, 3, 4};
//要素数分繰り返す
for (int i = 0; i < vec.size(); i++){
std::cout << vec[i] << std::endl;
}
3.6.2 iteratorを使用する
iteratorを使用してループすることもできる。
std::vector vec = {1, 2, 3, 4};
// ベクターの要素をイテレータを使用して繰り返す
for(auto it = vec.begin(); it != vec.end(); it++) {
std::cout << *it << std::endl;
}
この例は、iteratorを使用してデータを繰り返す例である。イテレータを使用しても配列にアクセスできる。
3.6.3 範囲ベースの繰り返し
範囲ベースの繰り返しもすることができる。
std::vector vec = {1, 2, 3, 4};
for (auto tmp : vec) {
std::cout << tmp.second(); << std::endl;
}
このように、範囲ベースでvectorを繰り返すこともできる。
3.7 ペアを使用する
std::pairとすることで、key:valueという形でvectorを使用することができる。
std::vector<std::pair<int, std::string>> vec;
vec.push_back({1, "Apple"});
vec.push_back({2, "Banana"});
vec.push_back({3, "Cherry"});
for(const auto& pair : vec) {
std::cout << pair.first << ": " << pair.second << "\n";
}
上記の例は、keyに数字、valueに文字列のペアとした配列である。std::pairを使用することで、ペアとして取り扱うこともできる。
3.8 データの末尾を削除する
データの末尾を削除する場合は、pop_backを使用する。
#include <iostream>
#include <vector>
int main() {
std::vector<int> vec = {1, 2, 3, 4, 5};
// ベクタが空でないことを確認
if (!vec.empty()) {
vec.pop_back(); // 末尾の要素を削除
}
// 結果を表示
std::cout << "Vector after pop_back: ";
for(int i : vec) {
std::cout << i << " ";
}
std::cout << std::endl;
return 0;
}
注意点は、vectorが空の状態で実行しないと未定義動作となる。
4. 終わりに
今回は、C++のvectorを使用方法を復習した。vectorを使用できると、プログラムがスムーズに組めるようになるので、気になった方は調べてみると良いと思う。