| 情報学部 | 菅沼ホーム | 全体目次 | 演習解答例 | 付録 | 索引 |
template <テンプレート引数宣言> 関数宣言または定義
/****************************/
/* 関数テンプレート */
/* coded by Y.Suganuma */
/****************************/
#include <iostream>
#include <string.h>
using namespace std;
/**************************/
/* クラスTestに関する定義 */
/**************************/
class Test {
public:
char *str;
int n;
Test () {}
Test (char *str1, int n1) {
str = new char [strlen(str1)+1];
strcpy(str, str1);
n = n1;
}
bool operator< (Test &t) // < に対するオーバーロード
{
return strcmp(str, t.str) < 0 ? true : false;
}
};
/****************************************/
/* 最小値を返す関数(関数テンプレート) */
/* a,b : 比較するデータ */
/****************************************/
template <class cl> cl min_t(cl a, cl b) {
return a < b ? a : b;
}
/**********************************************/
/* 最小値を返す関数(関数名のオーバーロード) */
/* a,b : 比較するデータ */
/**********************************************/
int min_o(int a, int b) {
return a < b ? a : b;
}
double min_o(double a, double b) {
return a < b ? a : b;
}
Test min_o(Test a, Test b) {
return strcmp(a.str, b.str) < 0 ? a : b;
}
/******************/
/* mainプログラム */
/******************/
int main()
{
// 関数テンプレート
int i = 0, j = 1;
double x = 10.0, y = 5.5;
Test a("xyz",1), b("abc", 2), c = min_t(a, b);
cout << "テンプレート:int " << min_t(i, j) << " double " << min_t(x, y) << " クラス Test (" << c.str << "," << c.n << ")\n";
// 関数名のオーバーロード
c = min_o(a, b);
cout << "オーバーロード:int " << min_o(i, j) << " double " << min_o(x, y) << " クラス Test (" << c.str << "," << c.n << ")\n";
return 0;
}
テンプレート:int 0 double 5.5 クラス Test (abc,2) オーバーロード:int 0 double 5.5 クラス Test (abc,2)
template <テンプレート引数宣言> class クラス名 {
・・・・・
};
// コンストラクタ(デストラクタも同様)
template <テンプレート引数宣言> クラス名 <テンプレート引数> :: クラス名 (引数)
{
・・・・・
};
// メンバー関数
template <テンプレート引数宣言> クラス名 <テンプレート引数> :: メンバー関数名 (引数)
{
・・・・・
};
/******************************/
/* クラステンプレート */
/* coded by Y.Suganuma */
/******************************/
#include <iostream>
using namespace std;
/**************************/
/* クラスTestに関する定義 */
/**************************/
class Test {
public:
char *str;
int n;
Test () {}
Test (char *str1, int n1) {
str = new char [strlen(str1)+1];
strcpy(str, str1);
n = n1;
}
};
/**********************/
/* クラスVectorの定義 */
/**********************/
template <class Tp, int sz> class Vector {
public:
Tp *p;
int size;
// コンストラクタ
Vector()
{
size = sz;
p = new Tp [size];
}
// 追加
bool add(int k, Tp v)
{
bool res = true;
if (k < 0 || k > size-1) {
cout << " 要素番号が不適当です\n";
res = false;
}
else
p[k] = v;
return res;
}
};
/********************************************/
/* コンストラクタ(クラスの外で記述する場合) */
/********************************************/
/*
template <class Tp, int sz> Vector <Tp, sz>::Vector()
{
size = sz;
p = new Tp [size];
}
*/
/******************************************/
/* データの追加(クラスの外で記述する場合) */
/* k : 追加する要素番号 */
/******************************************/
/*
template <class Tp, int sz> bool Vector <Tp, sz>::add(int k, Tp v)
{
bool res = true;
if (k < 0 || k > size-1) {
cout << " 要素番号が不適当です\n";
res = false;
}
else
p[k] = v;
return res;
}
*/
/************/
/* main関数 */
/************/
int main()
{
int k, ei, sw;
cout << "int(0) or Test(1) ? ";
cin >> sw;
/*
整数
*/
if (sw == 0) {
Vector <int, 3> iv;
cout << "*整数ベクトル*\n";
cout << " 要素番号は ";
cin >> k;
while (k >= 0) {
cout << " 要素は ";
cin >> ei;
if (iv.add(k, ei))
cout << " " << iv.p[k] << " を追加\n";
cout << " 要素番号は ";
cin >> k;
}
}
/*
クラスTestのオブジェクト
*/
else {
Vector <Test, 3> iv;
cout << "*クラスTestのオブジェクト*\n";
cout << " 要素番号は ";
cin >> k;
while (k >= 0) {
char str[10];
cout << " 要素(文字列と値)は ";
cin >> str >> ei;
Test t(str, ei);
if (iv.add(k, t))
cout << " (" << iv.p[k].str << "," << iv.p[k].n << ") を追加\n";
cout << " 要素番号は ";
cin >> k;
}
}
return 0;
}
int(0) or Test(1) ? 0 // int オブジェクトの場合
*整数ベクトル*
要素番号は 0
要素は 10
10 を追加
要素番号は 1
要素は 20
20 を追加
要素番号は -1
int(0) or Test(1) ? 1 // Test オブジェクトの場合
*クラスTestのオブジェクト*
要素番号は 0
要素(文字列と値)は abc 10
(abc,10) を追加
要素番号は 2
要素(文字列と値)は xyz -5
(xyz,-5) を追加
要素番号は -1
| array | 固定長のオブジェクトを保持するコンテナであり,各要素は連続して格納されます. |
|---|---|
| deque | deque は double-ended queue (二重終端キュー)の頭文字をとったものであり,シーケンスコンテナの一種です.vector と同様の機能を提供しますが,vector とは異なり,連続した位置のストレージに全ての要素を持つことを保証していません. |
| forward_list | 単方向リストを保持します. |
| list | 双方向リストを保持します. |
| map | 連想配列,つまり,添え字として数値以外(キー)を使用してデータを参照できる配列を保持します.set と同様,データは自動的にソートされます. |
| multimap | 同じキーを持つデータ(キーの重複)を許す map です. |
| multiset | 同じ値を持つ要素許す set です. |
| priority_queue | 優先順位付き待ち行列を保持します.要素を追加すると,優先順位に従いソートされます(デフォルトでは降順).STL コンテナの一部を利用して,特別な機能を持たせたクラスであり,コンテナアダプタと呼ばれています. |
| queue | 待ち行列を保持します.STL コンテナの一部を利用して,特別な機能(コンテナの一方から要素が挿入され,反対側から要素を取り出す)を持たせたクラスであり,コンテナアダプタと呼ばれています. |
| set | 要素を自動的にソートして保持し,要素自身をキーとした探索が可能です.map と似ていますが,map ではキーとデータを別々に保持します. |
| stack | スタックを保持します.STL コンテナの一部を利用して,特別な機能を持たせたクラスであり,コンテナアダプタと呼ばれています. |
| unordered_map | 標準の配列や vector と異なり,コンテナ内の要素へのアクセスは絶対的な位置(添え字)によるのではなくキーによります.コンテナ内の各要素は,キーのハッシュ値に基づきハッシュテーブルに格納されるため,決められた順序で並んでいるわけではありません.キーとそれに対応する値がペアとなった要素を持ち,かつ,同一のキー値を格納することはできません. |
| unordered_multimap | 標準の配列や vector と異なり,コンテナ内の要素へのアクセスは絶対的な位置(添え字)によるのではなくキーによります.コンテナ内の各要素は,キーのハッシュ値に基づきハッシュテーブルに格納されるため,決められた順序で並んでいるわけではありません.キーとそれに対応する値がペアとなった要素を持ち,かつ,同一のキー値を格納することができます. |
| unordered_multiset | 標準の配列や vector とは異なり,コンテナ内の要素へのアクセスは絶対的な位置(添え字)によるのではなく、キーによります.コンテナ内の各要素は,キーのハッシュ値に基づきハッシュテーブルに格納されるため,決められた順序で並んでいるわけではありません.キーそのものが要素でもあり,かつ,同一のキー値を格納することができます. |
| unordered_set | 標準の配列や vector とは異なり,コンテナ内の要素へのアクセスは絶対的な位置(添え字)によるのではなく、キーによります.コンテナ内の各要素は,キーのハッシュ値に基づきハッシュテーブルに格納されるため,決められた順序で並んでいるわけではありません.キーそのものが要素でもあり,かつ,同一のキー値を格納することはできません. |
| vector | 動的配列を保持します.C の配列と互換性を持ち,データ領域の連続性が保証されています.通常の動的配列の場合は,宣言時に大きさを宣言しなければなりませんが,vector の場合は必要ありません.また,要素数を途中で変更することも可能です. |
| ランダムアクセスイテレータ | 各要素にランダムにアクセスでき,かつ,要素の参照と設定が可能 |
|---|---|
| 双方向イテレータ | 前方及び後方に移動でき,かつ,要素の参照と設定が可能 |
| 前方イテレータ | 前方だけに移動でき,かつ,要素の参照と設定が可能 |
| 入力イテレータ | 前方だけに移動でき,かつ,要素の設定が可能 |
| 出力イテレータ | 前方だけに移動でき,かつ,要素の参照が可能 |
| ランダムアクセスイテレータ | *, ->, =, +, -, ++, --, [], <, >, <=, >=, -=, +=, ==, != |
|---|---|
| 双方向イテレータ | *, ->, =, ++, --, ==, != |
| 前方イテレータ | *, ->, =, ++, ==, != |
| 入力イテレータ | *, ->, =, ++, ==, != |
| 出力イテレータ | *, =, ++ |
#include <stdio.h>
#include <vector>
using namespace std;
int main()
{
vector<int> v;
vector<int>::iterator it; // イテレータ
vector<int>::reverse_iterator r_it; // 逆方向イテレータ
// 初期設定
printf("**初期設定**\n");
v.push_back(0);
v.push_back(4);
v.push_back(3);
v.push_back(1);
v.push_back(2);
for (it = v.begin(); it != v.end(); it++)
printf(" %d", *it);
printf("\n**後ろの 3 つを出力**\n");
it = v.begin() + 2; // vector の場合,ランダムアクセスイテレータであるため可能
while (it != v.end()) {
printf(" %d", *it);
it++;
}
printf("\n**逆方向に出力**\n");
for (r_it = v.rbegin(); r_it != v.rend(); r_it++)
printf(" %d", *r_it);
return 0;
}
**初期設定** 0 4 3 1 2 **後ろの 3 つを出力** 3 1 2 **逆方向に出力** 2 1 3 4 0
| insert_iterator | コンテナに要素を挿入する出力イテレータ.insert_iterator を生成する inserter() 関数を持っています. |
|---|---|
| front_insert_iterator | コンテナの最初に要素を挿入する出力イテレータ.push_front() を使用して実行するため,このメンバー関数を持つコンテナだけに適用できます.front_insert_iterator を生成する front_inserter() 関数を持っています. |
| back_insert_iterator | コンテナの最後に要素を挿入する出力イテレータ.push_back() を使用して実行するため,このメンバー関数を持つコンテナだけに適用できます.back_insert_iterator を生成する back_inserter() 関数を持っています. |
#include <stdio.h>
#include <deque>
using namespace std;
int main()
{
// 初期設定
printf("**初期設定 : q1**\n");
deque<int>::iterator it;
deque<int> q1;
for (int i1 = 0; i1 < 5; i1++)
q1.push_back(i1);
for (it = q1.begin(); it != q1.end(); it++)
printf(" %d", *it);
printf("\n");
printf("**初期設定 : q2**\n");
deque<int> q2;
for (int i1 = 0; i1 < 3; i1++)
q2.push_back(10 * (i1 + 1));
for (it = q2.begin(); it != q2.end(); it++)
printf(" %d", *it);
printf("\n");
// insert_iterator
printf("**2 番目の要素の前に 5 を挿入( insert_iterator )**\n");
it = q1.begin() + 1;
insert_iterator<deque<int> > i_it(q1, it);
*i_it = 5;
for (it = q1.begin(); it != q1.end(); it++)
printf(" %d", *it);
printf("\n");
// inserter
printf("**q1 の 3 番目の要素の前に q2 を挿入( inserter )**\n");
copy(q2.begin(), q2.end(), inserter(q1, q1.begin()+2));
for (it = q1.begin(); it != q1.end(); it++)
printf(" %d", *it);
printf("\n");
// front_insert_iterator, back_insert_iterator
printf("**最初と最後に 20 と 10 を挿入**\n");
printf("**( front_insert_iterator と back_insert_iterator )**\n");
front_insert_iterator<deque<int> > f_it(q1);
*f_it = 20;
back_insert_iterator<deque<int> > b_it(q1);
*b_it = 10;
for (it = q1.begin(); it != q1.end(); it++)
printf(" %d", *it);
printf("\n");
// back_inserter
deque<int> q3;
printf("**q2 を q3 にコピー( back_inserter )**\n");
copy(q2.begin(), q2.end(), back_inserter(q3));
// copy(q2.begin(), q2.end(), q3.begin()); // 挿入タイプでないとだめ
for (it = q3.begin(); it != q3.end(); it++)
printf(" %d", *it);
printf("\n");
// copy
printf("**q2 を q1 に上書きコピー**\n");
copy(q2.begin(), q2.end(), q1.begin()); // 上書きコピー
for (it = q1.begin(); it != q1.end(); it++)
printf(" %d", *it);
printf("\n");
return 0;
}
**初期設定 : q1** 0 1 2 3 4 **初期設定 : q2** 10 20 30 **2 番目の要素の前に 5 を挿入( insert_iterator )** 0 5 1 2 3 4 **q1 の 3 番目の要素の前に q2 を挿入( inserter )** 0 5 10 20 30 1 2 3 4 **最初と最後に 20 と 10 を挿入** **( front_insert_iterator と back_insert_iterator )** 20 0 5 10 20 30 1 2 3 4 10 **q2 を q3 にコピー( back_inserter )** 10 20 30 **q2 を q1 に上書きコピー** 10 20 30 10 20 30 1 2 3 4 10
#include <iostream>
#include <iterator>
#include <vector>
using namespace std;
int main()
{
vector<int> v;
vector<int>::iterator it;
istream_iterator<int> i_it(cin);
ostream_iterator<int> o_it(cout);
*i_it;
while (*i_it != 0) {
v.push_back(*i_it);
i_it++;
}
for (it = v.begin(); it != v.end(); it++) {
cout << " ";
*o_it = *it;
o_it++;
}
return 0;
}
10 20 30
01 #include <iostream>
02 #include <algorithm>
03 #include <numeric>
04 #include <vector>
05
06 using namespace std;
07
08 void print(int x) {
09 cout << " " << x;
10 }
11
12 int sq(int n) {
13 return n * n;
14 }
15
16 int main()
17 {
18 // 最大値(max)
19 int a = 10, b = 5;
20 // max
21 int mx = max(a, b);
22 // int mx = max({1, 10, 5, 3, 5});
23 // 条件演算子
24 // int mx = a > b ? a : b;
25 // if 文
26 // int mx = a;
27 // if (b > mx)
28 // mx = b;
29
30 cout << "max : " << mx << endl;
31 // 繰り返し
32 vector<int> v = {0, 1, 2, 3, 4};
33 cout << "v :";
34 // for_each,関数
35 for_each(v.begin(), v.end(), print);
36 // for_each,ラムダ式
37 // for_each(v.begin(), v.end(), [](int x){ cout << " " << x; });
38 // for 文
39 // for (auto x : v)
40 // cout << " " << x;
41
42 cout << endl;
43 // 部分和
44 vector<int> v1 = {1, 2, 3, 4, 5}, v2(5);
45 cout << "v1 :";
46 for (auto x : v1)
47 cout << " " << x;
48 cout << endl;
49 // transform_inclusive_scan,二項関数オブジェクト plus と 関数 sq
50 transform_inclusive_scan(v1.begin(), v1.end(), v2.begin(), plus(), sq); // 二項関数オブジェクト plus と 関数 sq
51 // transform_inclusive_scan,ラムダ式
52 // transform_inclusive_scan(v1.begin(), v1.end(), v2.begin(), [](int sum, int a){ return sum + a; }, [](int x){ return x * x; }); // ラムダ式
53 // for 文
54 // v2[0] = v1[0] * v1[0];
55 // for (int i1 = 1; i1 < 5; i1++)
56 // v2[i1] = v2[i1-1] + v1[i1] * v1[i1];
57
58 cout << "v2 :";
59 for (auto x : v2)
60 cout << " " << x;
61 cout << endl;
62
63 return 0;
64 }
max : 10
if (max(a,b) > x)
v : 0 1 2 3 4
v1 : 1 2 3 4 5 v2 : 1 5 14 30 55
| シーケンス変更なし <algorithm> | adjacent_find | 指定した範囲で,同じ要素が連続している(二項関数オブジェクトで指定された関係にある)位置を探します. |
|---|---|---|
| all_of | 範囲内の全ての要素が条件を満たすかを判定します. | |
| any_of | 範囲内のいずれかの要素が条件を満たすかを判定する. | |
| count | 指定した範囲で,指定した値と一致する要素の数を返します. | |
| count_if | 指定した範囲で,単項関数オブジェクトが真となる要素の数を返します. | |
| equal | first1 から last1 で指定した範囲が,first2 で指定された要素列と同じ(二項関数オブジェクトで指定した意味で同じ)場合に true を返します. | |
| find | 指定した範囲で,指定した要素を探します. | |
| find_end | first1 から last1 で指定した範囲内に,first2 から last2 に現れるシーケンスと同じ(二項関数オブジェクトで指定した意味で同じ)シーケンスが最後に現れた位置を返します. | |
| find_first_of | first1 から last1 で指定した範囲で,first2 から last2 に含まれるいずれかの要素と等しい(二項関数オブジェクトで指定した意味で等しい)要素が最初に表れた位置を返します. | |
| find_if | 指定した範囲で,単項関数オブジェクトが真になる要素を探します. | |
| find_if_not | 範囲の中から指定された条件を満たさない最初の要素を検索します. | |
| for_each | 指定した範囲に,指定した関数による処理を適用します. | |
| for_each_n | 範囲の先頭 n 個の要素に指定された関数を適用します. | |
| mismatch | first1 から last1 で指定した範囲が,first2 で指定された要素列と異なる(二項関数オブジェクトで指定した意味で異なる)位置を返します. | |
| none_of | 範囲内の全ての要素が条件を満たさないかを判定する. | |
| search | first1 から last1 で指定した範囲で,first2 から last2 で指定された要素列(二項関数オブジェクトで指定した意味で等しい要素列)が最初に表れた位置を返します. | |
| search_n | first1 から last1 で指定した範囲で,指定された要素の n 個の要素列(二項関数オブジェクトで指定した意味で指定した要素と等しい)最初に表れた位置を返します. | |
| シーケンス変更あり <algorithm> | copy | 指定した範囲をコピーします. |
| copy_backward | 指定した範囲を後方からコピーします. | |
| copy_if | 指定した範囲内の条件を満たした要素をコピーします. | |
| copy_n | 指定した位置から,指定した数の要素をコピーします. | |
| fill | 指定した範囲の要素を,指定した要素に設定します. | |
| fill_n | 指定した位置から始まる指定した数の要素を,指定した要素に設定します. | |
| generate | 指定した範囲の要素を,指定した関数によって生成された要素に設定します. | |
| generate_n | 指定した位置から始まる指定した数の要素を,指定した関数によって生成された要素に設定します. | |
| is_partitioned | 与えられた範囲が条件によって区分化されているか判定します. | |
| iter_swap | イテレータで指定した 2 つの要素を交換します. | |
| partition | 単項述語オブジェクトが真になる要素を偽になる要素の前に移動します.その際,最初の前後関係が維持されるとは限りません. | |
| partition_copy | 与えられた範囲を条件によって 2 つの出力の範囲へ分けてコピーします. | |
| partition_point | 与えられた範囲から条件によって区分化されている位置を得ます. | |
| remove | 指定した範囲の指定した要素を削除します.ただし,コンテナのサイズ自身は変化しません. | |
| remove_copy | 指定した範囲の指定した要素を削除し,指定した場所にコピーします.ただし,コピー元の要素は変化しません. | |
| remove_copy_if | 指定した範囲の単項関数オブジェクトが真になる要素を削除し,指定した場所にコピーします.ただし,コピー元の要素は変化しません. | |
| remove_if | 指定した範囲の単項関数オブジェクトが真になる要素を削除します.ただし,コンテナのサイズ自身は変化しません. | |
| replace | 指定した範囲の指定した要素を,指定した要素に置き換えます. | |
| replace_copy | 指定した範囲の指定した要素を,指定した要素に置き換え,指定した場所にコピーします.ただし,コピー元の要素は変化しません. | |
| replace_copy_if | 指定した範囲の単項関数オブジェクトが真になる要素を,指定した要素に置き換え,指定した場所にコピーします.ただし,コピー元の要素は変化しません. | |
| replace_if | 指定した範囲の単項関数オブジェクトが真になる要素を,指定した要素に置き換えます. | |
| reverse | 指定した範囲の要素の並び順を反転します. | |
| reverse_copy | 指定した範囲の要素の並び順を反転し,指定した場所にコピーします.ただし,コピー元は変化しません. | |
| rotate | イテレータ middle が指す要素が先頭になるように左方向に回転します. | |
| rotate_copy | イテレータ middle が指す要素が先頭になるように左方向に回転し,指定した場所にコピーします.ただし,コピー元は変化しません. | |
| sample | 指定された範囲から指定された個数の要素をランダムに抽出します. | |
| shuffle | 指定した範囲の要素を同じ確率で並び替える. | |
| stable_partition | 単項述語オブジェクトが真になる要素を偽になる要素の前に移動します.その際,最初の前後関係が維持されます. | |
| swap_ranges | イテレータ first1,last1 で指定した範囲を first2 で始まる範囲と交換します. | |
| transform | イテレータで指定された範囲の要素に対して,1 引数関数,または,2 引数関数の結果を適用し,指定した場所に保存します. | |
| unique | 指定した範囲内の隣り合った重複した要素(二項関数オブジェクトを真にする意味で隣り合った重複した要素)を削除します.ただし,コンテナのサイズ自身は変化しません. | |
| unique_copy | 指定した範囲内の隣り合った重複した要素(二項関数オブジェクトを真にする意味で隣り合った重複した要素)を削除し,指定した位置にコピーします.ただし,コピー元は変化しません. | |
| ソート関係 <algorithm> | binary_search | ソート済みの系列に対して,指定した範囲で,指定した要素を探します. |
| clamp | 値 v を指定した範囲 [low, high] 内に収めます. | |
| equal_range | ソート済みの系列に対して,指定した要素を系列の順序を破壊することなく挿入できる位置( lower_bound と upper_bound,value 以上の値の位置と value より大きい値の位置)を返します. | |
| includes | 最初の系列に後ろの系列のすべての要素が含まれているとき true を返します. | |
| inplace_merge | 2つの連続したソート済み範囲(同じ系列内の first から middle で指定した部分と,middle から last で指定した部分)をマージします. | |
| is_heap | 範囲がヒープ化されているかを判定します. | |
| is_heap_until | 範囲がヒープ化されているか判定し,ヒープ化されていない最初の要素を指すイテレータを返します. | |
| is_permutation | first2 または [first2, last2] で示された並びが,[first1, last1] を並び替えたものに存在するか否かを返す. | |
| is_sorted | 与えられた範囲がソート済みかを判定します. | |
| is_sorted_until | ソート済みか判定し,ソートされていない位置のイテレータを返します. | |
| lexicographical_compare | 2 つの系列をアルファベット順に比較し,先の系列が次の系列より辞書的に前にあれば true を返します. | |
| lower_bound | ソート済みの系列に対して,指定した要素以上の値を持つ最初の要素を返します. | |
| make_heap | ヒープを構築します. | |
| max | 2 つの値の内,または,初期化子リストの中から大きい方の値を返します. | |
| max_element | 指定した範囲において,最大要素を指す最初のイテレータを返します. | |
| merge | 2つのソート済み範囲をマージします. | |
| min | 2 つの値の内,または,初期化子リストの中から小さい方の値を返します. | |
| min_element | 指定した範囲において,最小要素を指す最初のイテレータを返します. | |
| minmax | 2 つの値の内,または,初期化子リストの中から最小値と最大値の組を返します. | |
| minmax_element | 指定した範囲において,最小要素及び最大要素を指すイテレータの組を返します. | |
| next_permutation | 系列の各要素を辞書的順序で並べた場合において,現在の並べ方の次になる並べ方を返します.次の並べ方が存在しない場合,辞書的順序における最初の並べ方に並べ替えます. | |
| nth_element | first から last によって指定した範囲を対象とし,nth で指定した要素より小さい要素をその前に,大きい要素をその後ろに移動します. | |
| partial_sort | first から last で指定した範囲をソートします.その際,ソートされるのは first から middle までであり,それ以降はばらばらとなります. | |
| partial_sort_copy | first から last で指定した範囲をソートし,他の範囲( result_first から result_last の間)に可能な限りコピーします. | |
| pop_heap | ヒープの先頭と末尾を入れ替え,ヒープを再構築します.末尾の要素は,pop_heap を実行しても,コンテナ内から要素が削除されるわけではなく,系列の最後に移動し,ヒープから外れるだけです. | |
| prev_permutation | 系列の各要素を辞書的順序で並べた場合において,現在の並べ方の前になる並べ方を返します.前の並べ方が存在しない場合,辞書的順序における最後の並べ方並べ替えます. | |
| push_heap | ヒープに要素を追加し,ヒープを再構築します.追加する要素は,前も使用するコンテナに追加しておく必要があります. | |
| set_difference | 系列 1 に含まれ,系列 2 に含まれない要素の集合( 2 つのソート済み範囲の差集合)を出力します.なお,2 つの系列は前もってソートしておく必要があります. | |
| set_intersection | 系列 1 ,及び,系列 2 の両方に含まれる要素の集合( 2 つのソート済み範囲の積集合)を出力します.なお,2 つの系列は前もってソートしておく必要があります. | |
| set_symmetric_difference | 系列 1 ,および,系列 2 に共通しない要素( 2 つのソート済み範囲の対称差集合)の集合を出力します.なお,2 つの系列は前もってソートしておく必要があります. | |
| set_union | 系列 1 ,または,系列 2 に含まれる要素の集合( 2 つのソート済み範囲の和集合)を出力します.なお,2 つの系列は前もってソートしておく必要があります. | |
| sort | 指定した範囲を並べ替えます. | |
| sort_heap | ヒープをソートします. | |
| stable_sort | 指定した範囲をソートします.その際,等しい要素の並び順が保持されます. | |
| upper_bound | ソート済みの系列に対して,指定した要素より大きい値を持つ最初の要素を返します. | |
| bitset クラス <bitset> | bitset | N ビットのビット集合を表すクラスです.添字演算子で任意の位置のビット状態を確認でき,文字列と整数値との相互変換が可能です. |
| 数学関係 <cmath> | 三角関数,逆三角関数 | 三角関数,逆三角関数 |
| 双曲線関数,逆双曲線関数 | 双曲線関数,逆双曲線関数 | |
| 指数関数,対数関数 | 指数関数,対数関数 | |
| 累乗,冪乗,絶対値 | 冪乗,平方和,平方根,立方根,絶対値 | |
| 切り上げ,切り捨て,四捨五入 | 天井関数,床関数,四捨五入,0 方向への丸め | |
| 剰余 | 商と剰余 | |
| 誤差関数,ガンマ関数 | 誤差関数,相補誤差関数,ガンマ関数,ガンマ関数の絶対値の自然対数 | |
| 特殊関数 | ラゲール陪多項式,ルジャンドル陪関数,ベータ関数,楕円積分,ベッセル関数,指数積分,エルミート多項式,ラゲール多項式,ルジャンドル多項式,リーマンのゼータ関数,球面調和関数のθ成分 | |
| 複素数 <complex> | 複素数 | 複素数を扱うクラスです. |
| 数値シーケンス <numeric> | accumulate | イテレータで指定された範囲の総和を計算します. |
| adjacent_difference | 隣接する要素間の差からなる系列を計算します. | |
| exclusive_scan | イテレータで指定された範囲の部分和(順番に和を求めながら,その段階までの和をその要素の値とする)を計算します.なお,inclusive_scan とは異なり,最後の要素は含まれず,また,生成される要素列の最初の要素は初期値に一致します. | |
| gcd | 最大公約数を求めます. | |
| inclusive_scan | イテレータで指定された範囲の部分和(順番に和を求めながら,その段階までの和をその要素の値とする)を計算します.なお,生成される要素列の最初の要素は,必ず,元の系列の最初の要素に一致します. | |
| inner_product | イテレータで指定された範囲で,2 つのコンテナ v1 と v2 の内積を計算します. | |
| iota | 指定された値から始まる整数列を生成します. | |
| lcm | 最小公倍数を求めます. | |
| partial_sum | イテレータで指定された範囲の部分和(順番に和を求めながら,その段階までの和をその要素の値とする)を計算します. | |
| reduce | イテレータで指定された範囲の総和を計算します. | |
| transform_exclusive_scan | イテレータで指定された範囲の部分和(順番に和を求めながら,その段階までの和をその要素の値とする)を計算します.部分和を求める際,最後の要素は除外されます. | |
| transform_inclusive_scan | イテレータで指定された範囲の部分和(順番に和を求めながら,その段階までの和をその要素の値とする)を計算します.部分和を求める際,最後の要素も対象とします. | |
| transform_reduce | イテレータで指定された範囲の総和を計算します. | |
| 乱数 <random> | Bernoulli | ベルヌーイ分布乱数,二項分布乱数,幾何分布乱数,負の二項分布乱数を生成します. |
| mt19937 | メルセンヌ・ツイスター法による擬似乱数生成エンジンです. | |
| normal | 正規分布乱数,対数正規分布乱数,カイ二乗分布乱数,コーシー分布乱数,フィッシャーの F 分布乱数,ステューデントの t 分布乱数を生成します. | |
| Poisson | ポワソン分布乱数,指数分布乱数,ガンマ分布乱数,ワイブル分布乱数,極値分布乱数を生成します. | |
| sampling | 確率分布生成器,重み付き確率分布生成器,線形重み付き確率分布生成器を生成します. | |
| uniform | 一様分布乱数を生成します. | |
| 文字列 <string> | string | 文字列を保持するクラスです. |
| タプル <tuple> | tuple | 複数の型の値を保持する「タプル」を表現するためのクラスです. |
| ユーティリティ <utility> | pair | 2 つのデータをペアにして扱うためのクラスです. |
| swap | 2 つの値を入れ替えます. |
| 単項関数オブジェクト | logical_not, negate |
|---|---|
| 二項関数オブジェクト | plus, minus, multiplies, divides, modulus, equal_to, not_equal_to, greater, greater_equal, less, less_equal, logical_and, logical_or |
#include <iostream>
#include <map>
using namespace std;
int main()
{
cout << "**コンテナ m1 (greater)**\n";
map<string, int, greater<string> > m1;
map<string, int, greater<string> >::iterator g_it;
m1.insert(pair<string, int>("suzuki", 40));
m1.insert(pair<string, int>("sato", 60));
m1.insert(pair<string, int>("yamada", 70));
m1.insert(pair<string, int>("tanaka", 50));
m1.insert(pair<string, int>("kato", 90));
for (g_it = m1.begin(); g_it != m1.end(); g_it++)
cout << " " << (*g_it).first << " " << (*g_it).second;
cout << endl;
cout << "**コンテナ m2 (less)**\n";
map<string, int, less<string> > m2;
map<string, int, less<string> >::iterator l_it;
m2.insert(pair<string, int>("suzuki", 40));
m2.insert(pair<string, int>("sato", 60));
m2.insert(pair<string, int>("yamada", 70));
m2.insert(pair<string, int>("tanaka", 50));
m2.insert(pair<string, int>("kato", 90));
for (l_it = m2.begin(); l_it != m2.end(); l_it++)
cout << " " << (*l_it).first << " " << (*l_it).second;
cout << endl;
return 0;
}
**コンテナ m1 (greater)** yamada 70 tanaka 50 suzuki 40 sato 60 kato 90 **コンテナ m2 (less)** kato 90 sato 60 suzuki 40 tanaka 50 yamada 70
01 #include <iostream>
02 #include <list>
03 #include <functional>
04 using namespace std;
05 // 単項関数オブジェクト
06 template <class T> class is_odd : public unary_function<T, bool> // bool は戻り値
07 {
08 public:
09 bool operator() (T k)
10 {
11 return (bool)(k % 2); // 0 以外は true に変換される
12 }
13 };
14 /* クラステンプレートを使用せず,かつ,unary_function を継承しない場合
15 class is_odd
16 {
17 public:
18 bool operator() (int k)
19 {
20 return (bool)(k % 2); // 0 以外は true に変換される
21 }
22 };
23 */
24 // 二項関数オブジェクト
25 class Equal : public binary_function<int, int, bool> // bool は戻り値
26 {
27 public:
28 result_type operator() (first_argument_type a, second_argument_type b)
29 {
30 return (result_type)(a == b);
31 }
32 };
33 /* binary_function を継承しない場合
34 class Equal
35 {
36 public:
37 bool operator() (int a, int b)
38 {
39 return (bool)(a == b);
40 }
41 };
42 */
43
44 int main()
45 {
46 list<int> ls;
47 list<int>::iterator it;
48 // 初期設定
49 printf("**初期設定**\n");
50 ls.push_back(0);
51 ls.push_back(2);
52 ls.push_back(3);
53 ls.push_back(4);
54 ls.push_back(1);
55 for (it = ls.begin(); it != ls.end(); it++)
56 cout << " " << *it;
57 cout << endl;
58 // 奇数である要素を削除
59 printf("**奇数である要素を削除**\n");
60 ls.remove_if(is_odd<int>()); // 単項関数オブジェクト
61 // ls.remove_if(is_odd()); // クラステンプレートを使用しない場合
62 // 結果を表示
63 Equal eq; // 二項関数オブジェクト
64 // equal_to<int> eq; // 組み込まれている equal_to を使用する場合
65 for (it = ls.begin(); it != ls.end(); it++) {
66 if (eq(*it, 2))
67 cout << " " << *it << " は 2 に等しい" << endl;
68 else
69 cout << " " << *it << " は 2 に等しくない" << endl;
70 }
71
72 return 0;
73 }
**初期設定** 0 2 3 4 1 **奇数である要素を削除** 0 は 2 に等しくない 2 は 2 に等しい 4 は 2 に等しくない
[キャプチャリスト](パラメータリスト){ 関数本体 }
01 #include <iostream>
02 #include <vector>
03 #include <algorithm>
04
05 using namespace std;
06
07 int fun(auto sb, int a, int b) {
08 return sb(a, b);
09 }
10
11 int main()
12 {
13 // ラムダ式の定義と利用
14 int a = 10, b = 5;
15
16 cout << "ラムダ式定義前 : a " << a << ",b " << b << ",c 未定義\n";
17 auto fun1 = [a, &b](int x, int y){ b *= 10; return a * x + b * y; };
18 // auto fun1 = [=, &b](int x, int y){ b *= 10; return a * x + b * y; }; // ok
19 // a は変更不可のため,下の定義は error,
20 // auto fun1 = [=, &b](int x, int y){ a *= 10; return a * x + b * y; };
21
22 auto fun2 = [a, b](int x){ return a * x + b; };
23 // auto fun2 = [=](int x){ return a * x + b; }; // ok
24 // この時点で変数 c は未定義のため,下の定義は error,
25 // auto fun2 = [=](int x){ return a * x + b + c; };
26
27 int c = 5;
28 a = 20;
29 // ラムダ式を定義した時点での変数 a の値がコピーされるため
30 // ラムダ式を使用する際の a の値は 10 となる
31 cout << "ラムダ式使用前 : a " << a << ",b " << b << ",c " << c << endl;
32 int res1 = fun1(1, 2);
33 int res2 = fun2(3);
34 auto fun3 = fun1; // 他の変数に代入 OK
35 int res3 = fun3(1, 2);
36 cout << "ラムダ式使用後 : a " << a << ",b " << b << ",c " << c << endl;
37 cout << " fun1 : " << res1 << ",fun2 : " << res2 << ",fun3 : " << res3 << endl;
38 // 関数の引数として利用(その1)
39 vector<int> v {1, 2, 3, 4, 5};
40 cout << "vector v :";
41 for_each(v.begin(), v.end(), [a](int x){ cout << " " << a * x; });
42 cout << endl;
43 // 関数の引数として利用(その2)
44 auto add = [](int x, int y) { return x + y; };
45 auto sub = [](int x, int y) { return x - y; };
46 auto add_sub = [](auto sb, int x, int y) { return sb(x, y); };
47 cout << "add(add_sub) : " << add_sub(add, 2, 3) << ",sub(add_sub) : " << add_sub(sub, 2, 3) << endl;
48 cout << "add(fun) : " << fun(add, 2, 3) << ",sub(fun) : " << fun(sub, 2, 3) << endl;
49
50 return 0;
51 }
ラムダ式定義前 : a 10,b 5,c 未定義 ラムダ式使用前 : a 20,b 5,c 5 ラムダ式使用後 : a 20,b 500,c 5 fun1 : 110,fun2 : 35,fun3 : 1010 vector v : 20 40 60 80 100 add(add_sub) : 5,sub(add_sub) : -1 add(fun) : 5,sub(fun) : -1
| 情報学部 | 菅沼ホーム | 全体目次 | 演習解答例 | 付録 | 索引 |