C++ で一般的に使用される STL (コンテナ クラス、コンテナ アダプタ、イテレータ、およびアルゴリズム)

【C++】STLの詳しい解説

間違いがある場合は、修正してください。

STLとは

C++ の STL (標準テンプレート ライブラリ)、つまり標準テンプレート ライブラリは、C++ 標準ライブラリの不可欠な部分です。豊富なテンプレート クラス、関数、アルゴリズムのセットを提供し、一般的に使用されるデータ構造とアルゴリズムの実装を簡素化し、コードの再利用性と保守性を向上させます。

STL は 3 つの主要コンポーネントで構成されます。

  • コンテナ: ベクター、リスト、マップ、セット、キュー、スタックなど、いくつかの異なるタイプのコンテナが提供されています。各コンテナには、さまざまなニーズを満たすための固有の機能とパフォーマンス特性があります。

  • イテレータ: さまざまなコンテナ内の要素を横断し、アルゴリズム実装のための統一インターフェイスを提供できる一連の共通イテレータ インターフェイスを提供します。

  • アルゴリズム: 並べ替え、検索、カウント、変換などの一連の汎用アルゴリズムを提供します。これらのアルゴリズムはさまざまな種類のコンテナに適用でき、優れたパフォーマンスと可読性を備えています。

STL の利点は、一般的で効率的で安全な標準ツールセットのセットを提供し、プログラマが一般的に使用されるデータ構造とアルゴリズムを実装しやすくなり、同時に安全で読みやすいデータ構造を作成できることです。コードが効率的になるため、開発とメンテナンスの難しさが軽減されます。

コンテナクラス

C++ STL のすべてのコンテナ クラスは次のとおりです。

  1. シーケンスコンテナ:
  • ベクトル: 動的配列。ランダム アクセスをサポートし、サイズを動的に拡張できます。
  • deque: 両端キュー。双方向アクセスをサポートし、最初と最後の要素を効率的に挿入および削除できます。
  • list: 二重リンクリスト。順次アクセスをサポートし、効率的に挿入および削除できます。
  1. 連想コンテナ:
  • セット: 赤黒の木をベースにした順序なしのコレクション。ユニークな要素があり、昇順に配置されています。
  • multiset: 赤黒ツリーに基づく順序なしのコレクション。要素を繰り返して昇順に並べることができます。
  • マップ: 赤黒ツリー、キーと値のペアのストレージ、および自動ソートに基づく連想配列。
  • multimap: 赤黒ツリーに基づく連想配列 キーは繰り返すことができ、キーと値のペアは挿入順に格納されます。
  1. 順序付けされていない連想コンテナ:
  • unowned_set: ハッシュ テーブルに基づく順序なしセット。ハッシュ値に従ってグループ化された一意の要素があり、検索複雑さは O(1) です。
  • unowned_multiset: ハッシュ テーブルに基づく順序なしのコレクション。要素は繰り返すことができ、ハッシュ値によってグループ化され、検索の複雑さは O(1) です。
  • unowned_map: ハッシュ テーブル、キーと値のペアのストレージ、自動拡張と再編成、および O(1) の検索複雑さに基づく連想配列。
  • unowned_multimap: ハッシュ テーブルに基づく連想配列。キーは繰り返すことができ、キーと値のペアは挿入順に格納され、検索複雑さは O(1) です。

コンテナアダプター

  • stack は、deque、vector、または list に基づいて実装されたスタック コンテナー アダプターであり、後入れ先出し (LIFO) 要素アクセスをサポートします。スタックの特殊性により、スタックの最上位からは挿入および削除操作のみが許可されるため、そのインターフェイスはベクター コンテナーに似ており、プッシュ、ポップ、トップなどの操作のみを提供します。
  • queue は、deque または list に基づいて実装されたキュー コンテナ アダプタであり、先入れ先出し (FIFO) 要素へのアクセスをサポートします。キューでは、要素を末尾から挿入し、要素を先頭から削除する必要があります。したがって、そのインターフェイスは deque コンテナーに似ており、プッシュ、ポップ、フロント、バックなどの操作のみを提供します。
  • priority_queue は、ベクトルに基づいて実装されたヒープ コンテナー アダプターであり、自動ソートと効率的な挿入および削除操作をサポートします。ヒープソートの実装にはバイナリヒープを維持する必要がありますが、C++ STL は優先キュー機能を簡単に実現できる優先キューコンテナアダプタを提供します。コンテナ アダプタはキューに似ていますが、要素が挿入されるたびに、キューの最初の要素が常に最大値 (または最小値) になるようにヒープの順序が自動的に調整されます。

コンポーネント

  • ペアは値のペアを格納するために使用されるコンテナ アダプタであり、連想配列やマッピング テーブルなどのデータ構造を定義するために使用できます。たとえば、ペアを使用して、文字列と整数、日付と時刻などを保存できます。ペアは、ベクター、マップ、セットなどの STL のアルゴリズムとコンテナを使用して操作できます。
  • ヒープはヒープソート アルゴリズムの一部であり、コンテナーやコンテナー アダプターではありません。make_heap、push_heap、pop_heap などの関数は、コンテナー内の要素をヒープソートするために STL で提供されます。make_heap 関数はコンテナをヒープに変換し、push_heap 関数はヒープに新しい要素を挿入し、pop_heap 関数はヒープの最上位要素を削除してヒープを再構築します。ヒープを使用してシーケンスをすばやく並べ替え、最も多くの値やその他の操作を見つけます。

イテレータ

C++ STL のイテレータは、コンテナ内の要素を走査するために使用でき、さまざまな STL コンテナを走査できる抽象的な概念です。C++ STL のすべてのイテレータは次のとおりです。

  • 入力反復子 (入力反復子): 入力反復子は一方向の移動のみをサポートし、コンテナー内の要素を読み取ることができます。たとえば、istream_iterator は、ファイルまたは入力ストリームからデータを読み取る入力反復子です。

  • 出力反復子 (出力反復子): 出力反復子も一方向の移動のみをサポートし、コンテナーにデータを書き込むことができます。たとえば、ostream_iterator は、データをファイルまたは出力ストリームに書き込む出力反復子です。

  • 前方反復子 (前方反復子): 前方反復子は一方向の移動をサポートし、コンテナー内の要素の読み取りと変更は可能ですが、同じ要素を繰り返し走査することはできません。たとえば、list と forward_list は両方とも前方反復子をサポートします。

  • 双方向イテレータ (双方向イテレータ): 双方向イテレータは、コンテナ内で要素を前後に移動できる双方向の移動をサポートします。たとえば、deque、set、multiset、map、multimap などは双方向イテレータをサポートします。

  • ランダム アクセス イテレータ (ランダム アクセス イテレータ): ランダム アクセス イテレータは、任意の方向への移動をサポートし、コンテナ内の任意の要素に直接アクセスでき、定数時間の加算、減算、およびランダム アクセス操作をサポートします。たとえば、ベクトル、文字列、配列はすべてランダム アクセス反復子をサポートします。

  • ⭐上記の 5 つのイテレータに加えて、C++ STL は、リバース イテレータ、挿入イテレータなど、他のタイプのイテレータも提供します。

一般に、C++ STL のイテレータは、コンテナ内の要素をトラバースするための標準化されたインターフェイスであり、さまざまなコンテナ上で簡単に操作でき、さまざまなトラバース メソッドを提供します。

アルゴリズム(関数)

一般的な数学関数

C++ STL の数学関数には主に次のものがあります。

  1. 算術演算:
  • プラス:加算演算。
  • マイナス:減算演算。
  • 乗算: 乗算演算。
  • 除算: 除算演算。
  • modulus: モジュロ演算。
    これらの算術関数は、合計や平均の計算など、コンテナの要素に対して要素ごとの算術演算を実行します。
  1. 一般的な数学関数:
  • abs: 絶対値を計算します。
  • sqrt: 平方根を計算します。
  • pow: 電力を計算します。
  • exp: 指数関数を計算します。
  • log: 自然対数を計算します。
  • log10: 10 を底とする対数を計算します。
  • 天井:切り上げ。
  • 床:切り捨て。
  • ラウンド:切り上げる。
  • max: 2 つの数値の最大値を返します。
  • min: 2 つの数値の最小値を返します。
    これらの関数は、プログラマがさまざまな数学的計算 (特定の数値の平方根の計算、特定の数値のべき乗の計算、特定の数値の指数関数の値の計算など) を実行するのに役立ちます。

さらに、STL は、次のような他の数学関数も提供します。

  1. 乱数発生器:
  • rand: 擬似乱数を生成します。
  • srand: 乱数ジェネレーターのシードを設定します。通常はシステム時刻をシードとして使用します。
    これらの関数は、プログラマがさまざまなランダム アルゴリズムを実装するための乱数を生成するのに役立ちます。

一般に、C++ STL では多くの数学関数と算術関数が提供されており、プログラマの開発作業を大幅に簡素化し、コードの保守性と可読性を向上させることができます。

よく使用される非数学関数

  • std::find(): 指定されたコンテナー内の要素を検索し、最初に一致した要素を指す反復子を返します。一致する要素が見つからない場合は、末尾の反復子が返されます。例えば:
std::vector<int> vec {1, 2, 3, 4, 5};
auto it = std::find(vec.begin(), vec.end(), 3);
if (it != vec.end()) {
    std::cout << "Found: " << *it << '\n';
}
  • std::count(): コンテナー内で指定された値が出現する回数をカウントします。例えば:
std::vector<int> vec {1, 2, 3, 4, 5, 3};
int count = std::count(vec.begin(), vec.end(), 3);
std::cout << "Count of 3: " << count << '\n';
  • std::copy(): 1 つのコンテナ (または反復子の範囲) から別のコンテナ (または場所) にデータをコピーします。例えば:
std::vector<int> src {1, 2, 3, 4, 5};
std::vector<int> dest(5);  // 目标容器需要预分配空间
std::copy(src.begin(), src.end(), dest.begin());
for (auto i : dest) {
    std::cout << i << ' ';
}
  • std::transform(): 要素の範囲に対して何らかの操作を実行し、結果をターゲット コンテナに配置します。たとえば、次のコードは vec コンテナ内の要素を 2 倍にして dest コンテナに格納します。
std::vector<int> vec {1, 2, 3, 4, 5};
std::vector<int> dest(vec.size());
std::transform(vec.begin(), vec.end(), dest.begin(),
               [](int i) { return i * 2; });
for (auto i : dest) {
    std::cout << i << ' ';
}
  • std::sort(): コンテナ内の要素を並べ替え、カスタム比較関数をサポートします。例えば:
std::vector<int> vec {5, 2, 4, 1, 3};
std::sort(vec.begin(), vec.end());  // 默认从小到大排序
for (auto i : vec) {
    std::cout << i << ' ';
}

他の

⭐ キーワード auto (STL の一部ではありません)

STL コンテナ、アルゴリズム、イテレータなどと密接に使用でき、コンテナ内の要素、アルゴリズムの戻り値、イテレータが指す型などの情報を簡単に推測できます。たとえば、STL コンテナを使用する場合、auto を使用してイテレータ型を定義できます。

std::vector<int> vec {1, 2, 3, 4, 5};
for(auto it = vec.begin(); it != vec.end(); ++it) {
    // 使用 auto 推导出迭代器类型为 decltype(vec)::iterator 
    std::cout << *it << " ";
}

C++11 より前では、STL コンテナのイテレータを使用する場合は、次のように長いイテレータ型名を記述する必要があります。

std::vector<int> vec {1, 2, 3, 4, 5};
for(std::vector<int>::const_iterator it = vec.begin(); it != vec.end(); ++it) {
    // 使用 std::vector<int>::const_iterator 进行迭代
    std::cout << *it << " ";
}

auto キーワードを使用すると、コードをより簡潔にして読みやすくし、エラーの可能性を減らすことができます。したがって、auto は STL の一部ではありませんが、STL を使用する場合は auto キーワードと一緒に使用されることがよくあります。

いくつかの一般的な使用法

int a[5] = {1, 3, 5, 7, 9};
for (auto x : a) cout << x;
cout << endl;

vector<int>v(7, 6);
for (auto x : v) cout << x;
cout << endl;

string s = "acdb";
for (auto x : s) cout << x;
cout << endl;

char c[5] = {'b', 'a', 'd', 'c'};
for (auto x : c) cout << x;

//	输出
13579
6666666
acdb
badc





アルゴリズム(関数)

一般的な数学関数

C++ STL の数学関数には主に次のものがあります。

  1. 算術演算:
  • プラス:加算演算。
  • マイナス:減算演算。
  • 乗算: 乗算演算。
  • 除算: 除算演算。
  • modulus: モジュロ演算。
    これらの算術関数は、合計や平均の計算など、コンテナの要素に対して要素ごとの算術演算を実行します。
  1. 一般的な数学関数:
  • abs: 絶対値を計算します。
  • sqrt: 平方根を計算します。
  • pow: 電力を計算します。
  • exp: 指数関数を計算します。
  • log: 自然対数を計算します。
  • log10: 10 を底とする対数を計算します。
  • 天井:切り上げ。
  • 床:切り捨て。
  • ラウンド:切り上げる。
  • max: 2 つの数値の最大値を返します。
  • min: 2 つの数値の最小値を返します。
    これらの関数は、プログラマがさまざまな数学的計算 (特定の数値の平方根の計算、特定の数値のべき乗の計算、特定の数値の指数関数の値の計算など) を実行するのに役立ちます。

さらに、STL は、次のような他の数学関数も提供します。

  1. 乱数発生器:
  • rand: 擬似乱数を生成します。
  • srand: 乱数ジェネレーターのシードを設定します。通常はシステム時刻をシードとして使用します。
    これらの関数は、プログラマがさまざまなランダム アルゴリズムを実装するための乱数を生成するのに役立ちます。

一般に、C++ STL では多くの数学関数と算術関数が提供されており、プログラマの開発作業を大幅に簡素化し、コードの保守性と可読性を向上させることができます。

よく使用される非数学関数

  • std::find(): 指定されたコンテナー内の要素を検索し、最初に一致した要素を指す反復子を返します。一致する要素が見つからない場合は、末尾の反復子が返されます。例えば:
std::vector<int> vec {1, 2, 3, 4, 5};
auto it = std::find(vec.begin(), vec.end(), 3);
if (it != vec.end()) {
    std::cout << "Found: " << *it << '\n';
}
  • std::find_if(): 指定された範囲内で条件を満たす最初の要素を検索し、その要素のイテレータを返します。例えば:
std::vector<int> vec {1, 2, 3, 4, 5};
auto it = std::find_if(vec.begin(), vec.end(), [](int i) {
    return i % 2 == 0;  // 查找第一个偶数
});
if (it != vec.end()) {
    std::cout << "found: " << *it << '\n';
}
  • std::count(): コンテナー内で指定された値が出現する回数をカウントします。例えば:
std::vector<int> vec {1, 2, 3, 4, 5, 3};
int count = std::count(vec.begin(), vec.end(), 3);
std::cout << "Count of 3: " << count << '\n';
  • std::copy(): 1 つのコンテナ (または反復子の範囲) から別のコンテナ (または場所) にデータをコピーします。例えば:
std::vector<int> src {1, 2, 3, 4, 5};
std::vector<int> dest(5);  // 目标容器需要预分配空间
std::copy(src.begin(), src.end(), dest.begin());
for (auto i : dest) {
    std::cout << i << ' ';
}
  • std::sort(): コンテナ内の要素を並べ替え、カスタム比較関数をサポートします。例えば:
std::vector<int> vec {5, 2, 4, 1, 3};
std::sort(vec.begin(), vec.end());  // 默认从小到大排序
for (auto i : vec) {
    std::cout << i << ' ';
}


bool cmp(int a,int b) {return a>b;}  // 自定义比较函数,从大到小排序
std::vector<int> vec {5, 2, 4, 1, 3};
std::sort(vec.begin(), vec.end(), cmp);
for (auto i : vec) {
    std::cout << i << ' ';
}
  • std::nth_element(): 指定された位置の要素がソート後に正しい位置になるように、指定された範囲内の要素を部分的にソートします。線形時間で順序なし配列の k 番目の要素を見つけ、左側のすべての要素がこの要素より小さく、右側のすべての要素がこの要素より大きい正しい位置に配置します。このうち、 iter_nth は検索対象区間の開始位置、 iter_nth + k は検索対象区間の終了位置、 comp はオプションのパラメータで、カスタム比較関数を指定します。例えば:
std::vector<int> vec {3, 1, 4, 2, 5};
std::nth_element(vec.begin(), vec.begin() + 2, vec.end());  // 将第三个元素放到正确的位置
for (auto i : vec) {
    std::cout << i << ' ';
}
  • std::accumulate(): 指定された範囲内の要素を累積し、範囲内の一連の値の合計を計算し、合計を返します。カスタム開始値と二項演算関数のサポート。例えば:
std::vector<int> vec {1, 2, 3, 4, 5};
int sum = std::accumulate(vec.begin(), vec.end(), 0);  // 从 0 开始累加 
std::cout << "Sum: " << sum << '\n';
  • std::fill(): 指定された値をコンテナ内のすべての要素に割り当てますコンテナを埋めるために任意のタイプの値を使用できます。例えば:
std::vector<int> vec(5);
std::fill(vec.begin(), vec.end(), 42);
for (auto i : vec) {
    std::cout << i << ' ';
}
  • std::memset(): メモリのブロックを埋めバイナリ データをバイトごとに埋めます。各バイトには同じ値が割り当てられます。例えば:
std::vector<int> v {1, 2, 3, 4, 5};
std::fill(v.begin(), v.end(), 0);
for (auto i : v) {
    std::cout << i << ' ';
}
  • std::min_element() および std::max_element(): 指定されたコンテナー内の最小要素と最大要素の反復子をそれぞれ返します。例えば:
std::vector<int> vec {1, 2, 3, 4, 5};
auto min_it = std::min_element(vec.begin(), vec.end());
auto max_it = std::max_element(vec.begin(), vec.end());
std::cout << "Min: " << *min_it << ", Max: " << *max_it << '\n';
  • std::lexicographical_compare(): 2 つのコンテナーの辞書編集上のサイズを比較します。例えば:
std::vector<int> vec1 {1, 2, 3};
std::vector<int> vec2 {3, 2, 1};
bool result = std::lexicographical_compare(vec1.begin(), vec1.end(),
                                           vec2.begin(), vec2.end());
std::cout << "vec1 < vec2: " << std::boolalpha << result << '\n';
  • std::merge(): 2 つの並べ替えられたコンテナーを 1 つの並べ替えられたコンテナーにマージします。例えば:
std::vector<int> vec1 {1, 3, 5};
std::vector<int> vec2 {2, 4, 6};
std::vector<int> dest(vec1.size() + vec2.size());
std::merge(vec1.begin(), vec1.end(), vec2.begin(), vec2.end(), dest.begin());
for (auto i : dest) {
    std::cout << i << ' ';
}
  • std::reverse(): 指定された範囲内の要素を反転します。例えば:
std::vector<int> vec {1, 2, 3, 4, 5};
std::reverse(vec.begin(), vec.end());
for (auto i : vec) {
    std::cout << i << ' ';
}
  • std::reverse_copy(): 指定された範囲内の要素を別のコンテナにコピーし、要素の順序を逆にします。例えば:
std::vector<int> src {1, 2, 3, 4, 5};
std::vector<int> dest(src.size());
std::reverse_copy(src.begin(), src.end(), dest.begin());  // 反转元素顺序并复制到 dest 中
for (auto i : dest) {
    std::cout << i << ' ';
}
  • std::unique():指定された range 内の隣接する重複排除操作を実行し、重複排除された範囲の終わりを指す反復子を返します。最初に並べ替えてから重複排除することをお勧めします例えば:
std::vector<int> vec {1, 2, 2, 3, 3, 3, 4, 5, 5};
auto it = std::unique(vec.begin(), vec.end());
vec.erase(it, vec.end());  // 删除去重后的冗余元素
for (auto i : vec) {
    std::cout << i << ' ';
}
  • std::unique_copy(): 指定された範囲内の要素をターゲット コンテナにコピーし、隣接する重複要素を削除します。例えば:
std::vector<int> vec {1, 2, 2, 3, 3, 3, 4, 5, 5};
std::vector<int> dest(vec.size());
auto end_it = std::unique_copy(vec.begin(), vec.end(), dest.begin());
for (auto it = dest.begin(); it != end_it; ++it) {
    std::cout << *it << ' ';
}
  • std::binary_search(): 二分検索アルゴリズムを使用して、指定された範囲内で指定された要素を検索し、検索が成功したかどうかを返します。この関数では、範囲内の要素が昇順で並べ替えられている必要があることに注意してください。例えば:
std::vector<int> vec {1, 2, 3, 4, 5};
bool result = std::binary_search(vec.begin(), vec.end(), 3);  // 在 vec 中查找元素 3
std::cout << "found: " << std::boolalpha << result << '\n';
  • std::next_permutation(): 置換が与えられると、次の置換を生成します。現在のキューが最後の場合は false を返します。完全な位置合わせによく使用されます例えば:
std::vector<int> vec {1, 2, 3};
do {
    for (auto i : vec) {
        std::cout << i << ' ';
    }
    std::cout << '\n';
} while (std::next_permutation(vec.begin(), vec.end()));  // 输出所有排列
  • std::partition(): 指定された述語を境界点として、述語が満たされるかどうかに応じてコンテナ内の要素を 2 つの部分に分割し、境界点イテレータを返します。例えば:
std::vector<int> vec {1, 2, 3, 4, 5};
auto it = std::partition(vec.begin(), vec.end(), [](int i) {
    return i % 2 == 0;  // 将偶数和奇数分开
});
for (auto i : vec) {
    std::cout << i << ' ';
}
  • std::stable_partition(): std::partition() に似ていますが、相対的な順序は変更されません。例えば:
std::vector<int> vec {1, 2, 3, 4, 5, 6};
std::stable_partition(vec.begin(), vec.end(), [](int i) {
    return i % 2 == 0;  // 将偶数和奇数分开,但保持相对顺序
});
for (auto i : vec) {
    std::cout << i << ' ';
}
  • std::partial_sum(): 指定された範囲内の要素に対して部分合計演算を実行し、結果 (現在の要素と以前のすべての要素の合計) を宛先コンテナーに入れます。例えば:
std::vector<int> vec {1, 2, 3, 4, 5};
std::vector<int> dest(vec.size());
std::partial_sum(vec.begin(), vec.end(), dest.begin());
for (auto i : dest) {
    std::cout << i << ' ';
}
  • std::iota(): 指定された範囲内の要素に値を増分的に割り当てます。例えば:
std::vector<int> vec(5);
std::iota(vec.begin(), vec.end(), 1);
for (auto i : vec) {
    std::cout << i << ' ';
}
  • std::rotate(): 指定された位置にある要素が範囲の末尾になるように、指定された範囲内の要素を指定された距離だけ回転します。これは、最初のいくつかの要素を抽出して最後に接続することと同じです。例えば:
std::vector<int> vec {1, 2, 3, 4, 5};
std::rotate(vec.begin(), vec.begin() + 2, vec.end());  // 将前两个元素移动到最后
for (auto i : vec) {
    std::cout << i << ' ';
}
  • std::adjacent_difference(): 指定された範囲内の隣接する要素に対して差分演算を実行し、結果を宛先コンテナーに配置します。例えば:
std::vector<int> vec {1, 2, 3, 4, 5};
std::vector<int> dest(vec.size());
std::adjacent_difference(vec.begin(), vec.end(), dest.begin());
for (auto i : dest) {
    std::cout << i << ' ';
}
  • std::inner_product(): 2 つの範囲内の要素の内積を計算し、結果を返します。例えば:
std::vector<int> vec1 {1, 2, 3};
std::vector<int> vec2 {4, 5, 6};
int result = std::inner_product(vec1.begin(), vec1.end(), vec2.begin(), 0);  // 对 vec1 和 vec2 中元素进行内积计算
std::cout << "inner product: " << result << '\n';
  • std::clamp(): 指定された値を指定された範囲内にクランプし、余分な部分を切り捨てます。例えば:
int value = 10;
int result = std::clamp(value, 1, 5);  // 将 value 限制在 [1, 5] 范围内
std::cout << "result: " << result << '\n';

下の場所はごちゃごちゃしていてまだ整理されていません。

下の場所はごちゃごちゃしていてまだ整理されていません。

下の場所はごちゃごちゃしていてまだ整理されていません。

下の場所はごちゃごちゃしていてまだ整理されていません。

共通機能

文字列処理(よく使われる)

  • find() は文字列を検索し、見つからない場合は -1 を返します。
  • str.replace(pos, len, str)
    replaces、指定された文字列の文字を開始位置 pos から len の長さで str に置き換えます。
str=str.replace(str.find("a"),2,"#");  //从第一个a位置开始的两个字符替换成#
str=str.replace(str.begin(),str.begin()+5,"#"); //用#替换从begin位置开始的5个字符
  • substr() は
    文字列をインターセプトし、a から b までの添え字を含む文字列を返します。
c=s.substr(a,b)//截取s的下标a开始的b的字符(不足或b不写则到结尾)并赋值给c

string s = "asdfg";
cout << s.substr(1,2) << endl;//此时会输出sd
  • 文字列比較
    Compare()、strcmp()
string s1="asd", s2="asd";
s1.compare(s2);
/*相等返回0, 大于返回1, 小于返回-1*/
char s1[10]="asd", s2[10]="zxc"
strcmp(s1, s2);
/*相等返回0*/
  • 文字列フリップ
    reverse() 関数には戻り値がありません
string str="asdf";
reverse(str.begin(),str.end());

文字列の長さを取得する

文字列型:s.length(), s.size()
文字型:strlen(s),sizeof(str)/sizeof(str[0]),s.length()

  • strlen() 関数によって計算される文字列の長さは有効な長さであり、文字列の末尾のターミネータ '\0' も含まれません。
  • length() 関数によって計算される文字列の長さには、文字列の末尾のターミネータ '\0' は含まれません。
  • sizeof() 演算子によって計算される長さには、文字列の末尾のターミネータ '\0' が含まれます。
    関数の仮パラメータによって渡される文字配列の長さを計算するために関数内で sizeof() が使用される場合、得られる結果はポインタです。長さは文字列の長さではなく、変数のバイト数に対応するため、ここでは注意してください。

文字/文字列を取得する

  • getline : スペースを使用できます。1
    行の値を取得するには文字列 getline(cin,s) を使用します。車を戻すには getchar() を覚えておいてください。
string str;
getline(cin,str);
  • getchar() : 文字を受け取り、スペース、キャリッジリターンを受け取ることができ、char にのみ適用され、キャリッジリターンを食べるためによく使用されます
  • cin.get : スペースは受け入れられますが、char にのみ適用され、指定された数の文字を取得します
char ch[20];
cin.get(ch, 11);//获取10个字符
char ch1;
cin.get(ch1);//获取1个字符,相当于ch1 = cin.get()
  • cin.getline() : スペースは受け入れられますが、char にのみ適用されます。使用法は cin.get() と似ており、指定された文字数を取得します。
char a[20];
cin.getline(a, 20);

char m[3][20];
for(int i=0;i<3;i++)
	cin.getline(m[i],20);
  • gets() : 文字列を受信します。スペースも受信できます。char にのみ適用されます。
char ch[20];
gets(ch);

配列/コンテナの処理

  • lower_bound/upper_bound は、
    順序付けられた配列またはコンテナ内でのみ動作できます。
(lower_bound(a,a+n,int num)-a):在数组a中找到第一个大于等于num的数字并返回其下标

int a[] = {1, 2, 3, 4, 5, 7, 8, 9};
printf("%d", lower_bound(a, a + 8, 6) - a);//-a不能少,因为是地址相减
输出5,a->a+8中第一个大于等于6的位置是5

(upper_bound(a,a+n,int num)-a):在数组a中找到第一个大于num的数字并返回其下标
  • sort()
    //素早い並べ替え、cmp 関数をカスタマイズでき、構造の並べ替えにも使用できます
bool compare(int a,int b){
	return a>b;//降序
}
sort(num,num+4,compare);
  • 2 つの関数max_element() と min_element() は、
    配列内の最大/最小値と最大/最小添字を迅速に取得するために使用されます。min_element
    () と max_element() のアプリケーション メソッドは同じです。
int num[6]={1,0,5,2,5,0};
cout << *max_element(num,num+6) << endl;
//则此时输出的是num数组的最大值5
cout << max_element(num,num+6)-num << endl;
//则此时输出的是num数组的最大值的下标2
  • unique
    重複排除関数
    注: unique は、この関数を使用する前に、sort() を使用して
    隣接する要素を並べ替える。さらに重要なのは、いわゆる重複排除は重複したコンテンツを削除するのではなく、重複したコンテンツをすべて最後に配置することです。
unique(data,data+n)//将date数组去重,n是数组长度
  • スワップ
    交換
swap(a,b)//a和b进行交换

  • reverse() 関数には戻り値がありませ
int num[3]={ 1, 2, 3 };
reverse( num, num+3 );//3是数组长度

vector<int> v = { 1, 2, 3 };
reverse(v.begin(),v.end());

string str="asdf";
reverse(str.begin(),str.end());
  • find()
    は配列内の値を検索します。find
    が見つかった場合は添字アドレスを返します。見つからなかった場合は
    配列の長さの位置を返します。 i = find (開始位置, 終了位置 + 1,私)
int num[] = {1, 2, 3};
int *index;
index = find(num, num+3, 3);//index是查找到3的所在地址
cout << index-num << endl;//用3所在地址减去数组首元素地址就是3的下标

index = find(num, num+3, 5);//找不到返回数组长度所在地址
cout << index-num << endl;
/*这里输出数组长度3*/

数学的思考

__gcd()
(最大公約数、最小公倍数)

最大公約数を見つけるには、ユニバーサル ヘッダー ファイルを呼び出します。

int gc = __gcd(4,8);
//如果用不了参考
int gcd(int a,int b){
    if(b==0) return a;
    else
        return gcd(b,a%b);
}

最小公倍数

int lcm(int a,int b){
	return a/__gcd(a,b)*b;
}

STL

  • next_permutation()
    完全な配置 これは STL です。最初に配列を昇順にソートすることに注意してください
//int型数组:
sort(num,num+3);
int num[3] = {5,2,6};
	sort(num,num+3);
	//先使用sort排个序
	do{
		for(int i=0;i<3;i++)
			cout << num[i] << "  ";
		cout << endl;
	}while(next_permutation(num,num+3)); 

//string型: 
string s;
	cin >> s ;
	sort(s.begin(),s.end());
	//先使用sort排个序
	do{
		cout << s << endl;
	}while(next_permutation(s.begin(),s.end())); 

コンテナクラス

ベクトル、スタック、キュー、マップ、ペア、ヒープ
ベクトル (vector)、両端キュー (deque)、リンク リスト (list)、コレクション (セット)、複数のコレクション (マルチセット)、マッピング (マップ)、および複数のマッピング (マルチマップ) )

一部の関数の使用法が完全に記憶されていません。
ループする場合は auto または iterator を使用してください

ベクター

コンテナー。動的配列に似ていますが、サイズは動的に変更できます。

Vector は要素の取得と最後の要素の操作では効率的ですが、中間要素の操作ではパフォーマンスが比較的低くなります。

vector<int>v

vector<int >b(a) //将a中的元素复制到b中

vector<int>a(100,6)//定义100个值为6的元素

vector<string>b(a.begin(),a.end()) //将动态数组a的元素值复制到b中

v.begin()//返回指向迭代器第一个元素的指针

v.end()//返回指向迭代器最后一个元素的指针

v.size()//返回当前vector使用数据量的大小

v.empty()//测试vector是否为空

v.front()//返回第一个元素的值

v.back()//返回最后一个元素的值

v.push_back(x)//在容器最后一个位置插入元素x

v.pop_back(x)//删除最后一个元素

//insert erase swap

v.clear()//清空

//Iterators迭代器

vector<int>::iterator iter1;
for (iter1 = v.begin(); iter1 != v.end(); ++iter1) {
        cout << ' ' << *iter1 << endl;   //[0,1,2,3,4,5,6,7,8,9]
}

queue<int> q:建立一个队列q,其内部元素类型是int。

q.push(a):将元素a插入到队列q的末尾。

q.pop():删除队列q的队首元素。

q.front():查询q的队首元素。

q.back():查询q的队尾元素。

q.size():查询q的元素个数。

q.empty():查询q是否为空。

設定

set<int>a;

a.insert()//往集合中添加元素,它的参数也是只有一个,就是你想要添加的元素,无返回值。

a.count()//查找出现在集合中的元素的个数,返回值要么是1要么是0
//因为集合的互异性,所以它的返回值要么是1要么是0。
//一般也可以用它来判断某个元素是否在该集合中。

a.begin()和a.end()
//是有返回值的,返回值分别是第一个指向该元素的迭代器和指向最后一个元素迭代器的下一个位置

a.erase()//函数是用来删除指定的元素,参数只有一个,并且是你想要删除的元素,无返回值

a.size()//得出集合中的元素个数。

a.empty()//判断该集合是否为空。 

a.clear()//清空集合中的元素。

スタック

stack<int> S;	//定义一个存储整数类型的栈

top()//返回一个栈顶元素的引用,类型为 T&。如果栈为空,返回值未定义。

push(const T& obj)//将对象压入栈顶
//这是通过调用底层容器的 push_back() 函数完成的。

push(T&& obj)//以移动对象的方式将对象压入栈顶。
//这是通过调用底层容器的有右值引用参数的 push_back() 函数完成的。

pop()//弹出栈顶元素。

size()//返回栈中元素的个数。

empty()//在栈中没有元素的情况下返回 true。

emplace()//用传入的参数调用构造函数,在栈顶生成对象。

ペア

//最下層は、データのペアを格納する構造を使用して実装されます

pair<T1, T2> p1;

p1.first = 1;
 
p1.second = 2.5;
 
cout<<p1.first<<' '<<p1.second<<endl;

地図

map<typename1, typename2> mp //typename1是键的类型,typename2是值的类型。

//map中的键是唯一的

map<char, int> mp; 
mp['c'] = 20;
cout << mp['c'];	//答案输出20

//map可以使用it->first来访问键,it->second来访问值

//map会以键从小到大的顺序自动排序

find()
map<char, int>::iterator it = mp.find('b');
cout << it->first << " " << it->second;

erase()
mp.erase(it)//it为需要删除的元素的迭代器
mp.erase(key)//key为要删除的映射的键
mp.erase(first, last)//其中,first为需要删除的区间的起始迭代器,last为需要删除的区间末尾迭代器的下一个地址,即为删除左闭右开的区间[first, last)

size()//获得map中映射的对数

clear()//清空map中的所有元素

順序なしマップ

unordered_map<string, int> umap; //定义

ヒープ

ヒープ
完全なバイナリ ツリー、親ノードは子ノードよりも小さくても大きくもありません

make_heap(v.begin(), v.end(), greater<int>());//生成一个小堆,第三个不加就默认最小堆,加greater<int>()则为最大堆

pop_heap(v.begin(), v.end(), greater<int>()); // 将堆的第零个元素与最后一个元素交换

v.pop_back(); // 删除最后位置的元素

リスト

ダブルリンクリストを使用した実装

おすすめ

転載: blog.csdn.net/weixin_45940369/article/details/131059386