std::vector

Contents

概要

C言語における配列では、定義時に予めサイズを指定し、その配列サイズの中でやりくりする必要がありました。

vectorは動的配列であり、後から要素数を変更することが出来ます。

詳しい使い方はよその丁寧に説明されているサイトを見て、どうぞ。

イテレータ

vectorとお友達になるにはイテレータを知る必要があります。ググって。

Tips

競プロは時間との勝負なので、defineやusingを使って積極的にタイプ数を減らしましょう。

std::vector<long long> vec;
// ...
std::sort(vec.begin(), vec.end());

// とするが毎回このように記述するのは面倒なので
using namespace std;
using ll = long long;
using vll = vector<ll>;
#define all(v) v.begin(), v.end()

// と予め記述しておけば
vll vec;
// ...
sort(all(v));
// と省略できる

vector系はとりあえず何でも省略しておいたほうが楽なので、二次元配列くらいまではusingで型エイリアスを貼って省略しちゃいましょう。

using ll = long long;
using ld = long double;

using vi = vector<int>;
using vvi = vector<vi>;
using vll = vector<ll>;
using vvll = vector<vll>;
using vb = vector<bool>;
using vs = vector<string>;

 

頻出メソッド

キーワードを書きなぐっておきます。
詳しい使い方は丁寧なサイトを見てどうぞ。

vector::begin

vectorの始めの要素を指すiteratorを返します。

vector::end

vectorの末尾の次を示すiteratorを返します。

vector::rbegin

vectorの末尾の要素を指すイテレータを返します。
逆順で見れます。

vector::rend

先頭要素の前を指す逆イテレータを返します。

vector::size

vectorの要素数を返します。

vector::push_back

vectorの末尾に要素を追加します。

vector::emplace_back

push_backの強いバージョン(正確には違う)。

std::pairやstd::tupleのvectorを使用する場合、こっちのほうが高速かつ便利。

vector::erase

vector内の任意の箇所の要素を削除します。
重いので基本使わない。

vector::insert

vector内の任意の箇所に要素を追加します。
重いので基本使わない。

eraseやinsertを使う必要がある場合、std::set等の別の型を使用したほうが良い可能性が高いです。

関連メソッド

以下の機能を用いれば、vectorをもっと便利に扱えます。

これ以降で紹介する機能を用いるにはそれぞれに対応したヘッダーファイルをincludeする必要がありますが、どれがどれとか毎回紹介するのは面倒なので割愛します。
GCCならとりあえずbits/stdc++.hをincludeしておけば、全部使えるようになります。

#include <bits/stdc++.h>

std::sort

vector内の要素を昇順でソートします。

std::sort(v.begin(), v.end());

// 以下の表現でも同じ動作をする
#define all(v) v.begin(), v.end()
std::sort(all(v));

また、第3引数に比較関数を指定することで、好きなようにソートすることも出来ます。

// 降順ソート
bool comp(const ll &lhs, const ll &rhs) {
  return lhs > rhs;
};

std::sort(all(v), comp);

// ただの降順ならSTLで用意されている
std::sort(all(v), std::greater<ll>());

計算量は配列の長さをNとした時、O(N logN)となります。

std::find

template< class InputIterator, class T >
InputIt find( InputIterator first, InputIterator last, const T& value );

範囲 [first, last) 内の特定の基準を満たす最初の要素を取得します。
その様な要素がない場合、lastを返します。

計算量は配列の長さをNとした時、O(N)となります。

std::binary_search

template< class ForwardIt, class T >
bool binary_search( ForwardIt first, ForwardIt last, const T& value );

template< class ForwardIt, class T, class Compare >
bool binary_search( ForwardIt first, ForwardIt last, const T& value, Compare comp );

二分探索でvector内に目的の値が存在するかを確認します。
存在すればtrue、しなければfalseを返します。

※使用先のvectorは予め昇順にsortされている必要があります。特殊な順番でソートしている場合、sort時と同じ比較関数を第4引数のcompに指定してください。

計算量は配列の長さをNとした時、O(logN)となります。

std::lower_bound

template< class ForwardIterator, class T >
ForwardIt lower_bound( ForwardIterator first, ForwardIterator last, const T& value );

template< class ForwardIterator, class T, class Compare >
ForwardIt lower_bound( ForwardIterator first, ForwardIterator last, const T& value, Compare comp );

二分探索を用い、範囲 [first, last) 内の value 以上の最初の要素を指すイテレータを取得します。
そのような要素がない場合、 last を返します。

※使用先のvectorは予め昇順にsortされている必要があります。

計算量は配列の長さをNとした時、O(logN)となります。

std::upper_bound

template< class ForwardIterator, class T >
ForwardIt upper_bound( ForwardIterator first, ForwardIterator last, const T& value );

template< class ForwardIterator, class T, class Compare >
ForwardIt upper_bound( ForwardIterator first, ForwardIterator last, const T& value, Compare comp );

二分探索を用い、範囲 [first, last) 内の value より大きい最初の要素を指すイテレータを取得します。
そのような要素がない場合、 last を返します。

※使用先のvectorは予め昇順にsortされている必要があります。

計算量は配列の長さをNとした時、O(logN)となります。

std::next_permutation

vector内の要素を入れ替えていき、順列の全列挙を行います。
※使用先のvectorは予め昇順にsortされている必要があります。

  • 使用例
sort(all(v));
do {
  // do something
} while (next_permutation(all(v)));

// sortの仕方が特殊な場合はnext_permutationの第3引数にも比較関数を指定する
std::sort(all(v), comp);
do {} while (next_permutation(all(v), comp));

例題