「std::deque」の版間の差分
提供: C++入門
行1: | 行1: | ||
− | [[std::deque]] とは、Dobule Ended Queue の略です。双方向キュー、両端キューなどと呼ばれるデータ構造の[[STL]] [[コンテナ]] | + | [[std::deque]] とは、Dobule Ended Queue の略です。双方向キュー、両端キューなどと呼ばれるデータ構造の[[STL]] [[コンテナ]]です。dequeは、FIFOとFIFOの両方に対応したデータ構造です。先頭や末尾の挿入や削除の頻度が高い場合は、[[std::deque]]を使用します。 |
'''読み方''' | '''読み方''' | ||
行12: | 行12: | ||
* 先頭や一番後ろに要素を追加できます。 | * 先頭や一番後ろに要素を追加できます。 | ||
* .at や operator[] による添字でのアクセスが可能です。 | * .at や operator[] による添字でのアクセスが可能です。 | ||
+ | == std::deque を利用するシーン == | ||
+ | [[コンテナ]]は、それぞれ特徴があります。メモリの効率が良い、検索スピードが速い、先頭や末尾への挿入や削除が速い、途中への挿入や削除が速い、などの違いがあります。 | ||
+ | <u>先頭や末尾の挿入や削除の頻度が高い場合は、[[std::deque]]を使用します</u>。 | ||
+ | |||
+ | どの[[コンテナ]]を利用すべきかは、[[コンテナ]]をご参照ください。 | ||
== 要素の追加 == | == 要素の追加 == | ||
; push_front : 最初に要素を追加 | ; push_front : 最初に要素を追加 |
2015年11月8日 (日) 14:51時点における最新版
std::deque とは、Dobule Ended Queue の略です。双方向キュー、両端キューなどと呼ばれるデータ構造のSTL コンテナです。dequeは、FIFOとFIFOの両方に対応したデータ構造です。先頭や末尾の挿入や削除の頻度が高い場合は、std::dequeを使用します。
読み方
- std::deque
- えすてぃーでぃー でっく
- double ended queue
- だぶる えんでっど きゅー
目次
概要
発音は、「デキュー」ではありません。
std::dequeの特徴をいくつか挙げます。
- 先頭や一番後ろに要素を追加できます。
- .at や operator[] による添字でのアクセスが可能です。
std::deque を利用するシーン
コンテナは、それぞれ特徴があります。メモリの効率が良い、検索スピードが速い、先頭や末尾への挿入や削除が速い、途中への挿入や削除が速い、などの違いがあります。
先頭や末尾の挿入や削除の頻度が高い場合は、std::dequeを使用します。
要素の追加
- push_front
- 最初に要素を追加
- push_back
- 一番後ろに要素を追加
要素の削除
- pop_front
- 最初の要素を削除
- pop_back
- 一番後ろの要素を削除
デックのシンプルな例 deque1.cpp の例
ソースコード deque1.cpp
/* * deque1.cpp * Copyright (C) 2014 kaoru <kaoru@bsd> */ #include <iostream> #include <deque> using namespace std; template<typename T> void print(deque<T>& d) { for(auto x: d) { cout << x << " "; } cout << endl; } int main(int argc, char const* argv[]) { deque<int> d1; d1.push_back(1); d1.push_back(2); d1.push_back(3); d1.push_back(4); d1.push_front(0); print<int>(d1); // 0 1 2 3 4 d1.pop_back(); d1.pop_front(); print<int>(d1); // 1 2 3 d1.front() = 0; d1.back() = 9999; print<int>(d1); // 0 2 9999 return 0; }
コンパイル
g++49 -std=c++11 -I/usr/local/lib/gcc49/include/c++/ \ -Wl,-rpath=/usr/local/lib/gcc49 deque1.cpp -o deque1
実行例
% ./deque1 0 1 2 3 4 1 2 3 0 2 9999
atを使用した要素アクセスの例 deque_at1.cpp
atを使用してアクセスする場合、境界チェックが行われます。 存在しない要素にアクセスしようとすると std::out_of_range の例外がスローされます。operator[] を使用した場合には、例外は、スローされません。
ソースコード deque_at1.cpp
/* * deque1.cpp * Copyright (C) 2014 kaoru <kaoru@bsd> */ #include <iostream> #include <deque> #include <stdexcept> // std::out_of_range using namespace std; int main(int argc, char const* argv[]) { deque<int> d1; d1.push_back(1); d1.push_back(2); d1.push_back(3); d1.push_back(4); try { cout << d1.at(0) << endl; cout << d1.at(1) << endl; cout << d1.at(2) << endl; cout << d1.at(3) << endl; } catch (out_of_range e) { cerr << e.what() << endl; } try { cout << d1.at(4) << endl; // This is out of range } catch (out_of_range e) { cerr << e.what() << endl; } return 0; }
コンパイル
c++ deque_at1.cpp -o deque_at1
実行例
% ./deque_at1 1 2 3 4 deque::_M_range_check: __n (which is 4)>= this->size() (which is 4)
operator[]を使用した例 deque_at2.cpp
ソースコード deque_at2.cpp
/* * deque1.cpp * Copyright (C) 2014 kaoru <kaoru@bsd> */ #include <iostream> #include <deque> #include <stdexcept> // std::out_of_range using namespace std; int main(int argc, char const* argv[]) { deque<int> d1; d1.push_back(1); d1.push_back(2); d1.push_back(3); d1.push_back(4); try { cout << d1[0] << endl; cout << d1[1] << endl; cout << d1[2] << endl; cout << d1[3] << endl; } catch (out_of_range e) { cerr << e.what() << endl; } try { cout << d1[4] << endl; // 存在しないが例外とならない cout << d1[5] << endl; // 存在しないが例外とならない } catch (out_of_range e) { cerr << e.what() << endl; } return 0; }
コンパイル
c++ deque_at2.cpp -o deque_at2
実行例
添字の 0 から 3 までは、存在している要素なので、問題ありません。 添字 4, 5 は、存在しないのですが、 0 が返ってきています。
% ./deque_at2 1 2 3 4 0 0