0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

std::vectorチュートリアル

Last updated at Posted at 2021-07-03

C++の標準ライブラリにはvectorという配列の便利なバージョンみたいなのがあります。
いきなり例を示していきます。以下では全てiostreamvectorをincludeした上で試してみてください。

#include <iostream>
#include <vector>

vectorを作ってfor文で回してみる

std::vector<int> v = {2, 4, 6, 8, 10};
for (int i = 0; i < 5; ++i) std::cout << v[i] << "\n";

(ちなみにstd::vector<int> v;と宣言すれば要素数0のvectorができます。)
atでも参照できる

for (int i = 0; i < 5; ++i) std::cout << v.at(i) << "\n";

atを使うと存在しない要素(i=8番目とか)を参照しようとするとちゃんとエラーメッセージを出してくれます。そのチェックのために少し動作が遅くなるけど。

vectorの末尾に値を加える

v.push_back(12);
for (int i = 0; i < 6; ++i) std::cout << v.at(i) << "\n";

要素数を知る

std::cout << v.size() << "\n";

1から100000までの自然数の中から7の倍数だけをvectorに詰めよう。

std::vector<int> v;
for (int i = 1; i <= 100000; ++i) {
  if (i % 7 == 0) v.push_back(i);
}

実はこれだとpush_backの度にいちいちメモリを確保する動作が内部的に入って無駄に時間がかかります。先に必要な要素数に対応するメモリをreserveで予約しておこう。これで速くなります。

std::vector<int> v;
v.reserve(20000);
for (int i = 1; i <= 100000; ++i) {
  if (i % 7 == 0) v.push_back(i);
}

ここでpush_backされる要素の数は予約した20000より少ないですが大丈夫です。例えば10000要素分だけreserveするとかでも大丈夫です。ざっくりとでOK。
このvectorの中から1000の倍数だけ出力してみましょう。

int length = v.size();
for (int i = 0; i < length; ++i) {
  if (v[i] % 1000 == 0) std::cout << v[i] << "\n";
}

for文の条件式で要素数分繰り返すような工夫をしているのは1つのポイント。
あと些細なことですがif文の条件式のところはif (!(v[i] % 1000))と書き換えても同じ結果になりますね。
(ちなみにさっきから改行で"\n"を使っていますが、これはstd::endlよりもちょっと速いです。++iと前置インクリメントにしているのも一応速さを意識していますが、これは後置でもあまり変わらないかも)
lengthを定義せずにfor文のところで

for (int i = 0; i < v.size(); ++i) {...}

としたい人がいるかもしれませんが、for文の繰り返しの数だけvのサイズを計算させることになってしまい処理が遅くなるのでやめておきましょう。

上記でfor文の条件式について色々書きましたが、vectorの要素を最初から最後まで見たい時は範囲ベースfor文を使ってみましょう。

for (auto&& x : v) {
  if (!(x % 1000)) std::cout << x << "\n";
}

こうするとlengthなんて定義しなくて良いしfor文の条件式についても悩む必要はなくなります。さらに、処理がとても速くなります。

ループの途中で例えば1000の倍数の時だけ要素の値を5に更新するとかもできます。

for (auto&& x : v) {
  if (!(x % 1000)) x = 5;
}

一方、このような値の書き換えをせずに先程のcoutの時みたいに単に要素を参照するだけならば、const修飾子を使うとさらに速く処理できるらしいです。

for (const auto& x : v) {
  if (not (x % 1000)) std::cout << x << "\n";
}

!notに書き換えてみました。全く同じ動作をします。
vectorを空っぽにして最初の状態に戻すにはこうしましょう。

v.clear();
v.shrink_to_fit();
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?