C++のSTL
C++におけるSTLとはStandard Template Libraryのことである。
標準のtemplateクラスを提供している。よく使うっぽいので簡素にまとめる。
イテレータ
STLのクラスはイテレータが使える。 vectorはインデックスが使えるのでイテレータを使う場面は少ないかもしれないと思ったが。
イテレータを使用できるクラスが持つメソッド
メソッド名 | 内容 | 使用できるクラス |
---|---|---|
begin() | イテレータを返す | vector, list, map, set |
end() | リストの最後を表す(イテレータとの比較に使用) | vector, list, map, set |
insert(iterator, T) | イテレータの現在位置に挿入 | vector, list |
remove(iterator) | 現在位置のイテレータを削除 | list |
イテレータの演算子
演算子 | 内容 |
---|---|
itr++(後置インクリメント) | イテレータを1つすすめる |
itr += n | イテレータをnすすめる |
itr – | イテレータを1つ戻す |
itr -= | イテレータをn戻す |
itr*(ポインタの中身) | 現在のイテレータの中身を返す(代入も可) |
ソース(リストでの例)
#include<iostream> #include<list> //listをインクルード using namespace std; int main() { //宣言 list<int> l; //指定箇所に挿入 list<int>::iterator itr; itr = li.begin(); itr++; //イテレータを進める li.insert(itr, 20); //進めた先で挿入 //イテレータを走査しながら表示 for (itr = li.begin(); itr != li.end(); itr++) { cout << *itr << endl; } return 0; }
vector
vectorというと固定長の次元を持つ構造体を想像するが、どちらかというと動的配列に近い。 配列なので添字でアクセスできる。
メソッド名 | 内容 |
---|---|
void push_back(T) | 後方に追加 |
void pop_back() | 後方を削除 |
int size() | 個数を返す |
void clear() | 空にする |
bool empty() | 空かどうかを返す |
ソース
#include<iostream> #include<vector> //vectorのincludeが必要 using namespace std; int main() { //宣言 vector<int> v; //挿入 v.push_back(1); v.push_back(2); v.push_back(3); //削除(値は返ってこない) v.pop_back(); for (int i = 0; i < v.size(); i++) { //size()で反復回数を指定 cout << v[i] << endl; // 1 2を出力(配列のようにv[i]の形でアクセス可) } //クリア v.clear(); return 0; }
list
内部では双方向の連結リストになっているため、挿入や削除を頻繁に行うときにはこちらを使うべき。データ構造故にvectorのように添字でアクセスするには向かない。
メソッド名 | 内容 |
---|---|
void push_back(T), void push_front(T) | 後方に追加, 前方に追加 |
void pop_back(), void pop_front() | 後方を削除, 後方を削除 |
int size() | 個数を返す |
void clear() | 空にする |
bool empty() | 空かどうかを返す |
ソース
#include<iostream> #include<list> //listをインクルード using namespace std; int main() { //宣言 list<int> li; //挿入 li.push_back(20); //後方に挿入 li.push_back(30); li.push_front(10); //前方に挿入 //イテレータを走査しながら表示 for (itr = li.begin(); itr != li.end(); itr++) { cout << *itr << endl; //10 20 30 } return 0; }
map
mapとはPHPでいう連想配列、Swiftでいうディクショナリ型。 mapの中身は自動的にソートされるのでpush_backみたいなメソッドは存在せず、insertで挿入する。配列に代入する形でもおk。
mapのメソッド
メソッド名 | 内容 |
---|---|
begin() | イテレータを返す |
end() | リストの最後を表す(イテレータとの比較に使用) |
insert(first, second) | イテレータの現在位置に挿入 |
イテレータの演算子
mapは要素ごとに値を2つもつので以下のように取り出す。
演算子 | 内容 |
---|---|
itr->first, itr->second | 最初の要素、2つ目の要素 |
ソース
#include<iostream> #include<string> #include<map> using namespace std; int main() { map <string, int> score; score["Yaruo"] = 30; score["Yaranaio"] = 60; score["Dekiruo"] = 100; map <string, int>::iterator itr; for (itr = score.begin(); itr != score.end(); itr++) { cout << itr->first << ":" << itr->second << endl; } cout << score["Yaruo"] << endl; return 0; }
set
setはPython、Pascalでいう集合型。同じ要素を重複しない場合に使用する。
setのメソッド
メソッド名 | 内容 |
---|---|
insert(T) | 値を挿入 |
find(T) | 集合に存在するか検索(存在しなければend()を返す) |
#include<iostream> #include<string> #include<set> using namespace std; int main() { set<string> names; names.insert("Yaruo"); names.insert("Yaranaio"); names.insert("Yaruo"); //すでに存在するので追加されない names.insert("Dekiruo"); set<string>::iterator itr; for (itr = names.begin(); itr != names.end(); itr++) { cout << *itr << endl; } if (names.find("Gyaruo") != names.end()) { cout << "ギャル夫いるお" << endl; //出力されない } if (names.find("Yaruo") != names.end()) { cout << "やる夫いるお" << endl; //出力される } return 0; }