C++ の map::begin と map::end

この記事では、C++ STL の map::begin と map::end の概念と C++ コード例について説明しました。

目次

以下は、この記事で説明する内容のリストです

  • maps の紹介
  • map の使用
  • map の要素へのアクセス
  • begin() の使用 map の関数
  • end() の使用 マップ内の機能

地図の概要

地図 c++ の特別なデータ構造です 、キーと値のペアの形式でデータを保存します。それらは map と呼ばれます このデータ構造の各キーはマップされるため 対応する値に。地図は二分探索木を使用します これらのキーと値のペアを保存します。 pair を使用しています キーを対応する値にマップするためのデータ構造。

地図の使用

マップは、任意のタイプの特定のオブジェクトのプロパティを格納する、データの膨大なコレクションから任意のオブジェクトを検索する、順序付けられたデータを格納するなど、さまざまな目的に使用できます。

地図の例

// Example to demostrate basic use of a map

#include <iostream>
#include <map>

using std::map;
using std::cout;

int main () {
     map<char, int> example;
     
     example['z'] = 11;
     example['x'] = 12;
     example['y'] = 13;
     
     cout << "Printing the contents of a map:\n";
     for (auto iter:example) {
         cout << iter.first << ": " << iter.second << '\n';
     }
     
     return 0;
}

上記のコードは、次の出力を生成します:

Printing the contents of a map:
x: 12
y: 13
z: 11

注:上記の C++ のマップの例からわかるように、格納されたデータはキーの順序で並べ替えられます

地図の要素へのアクセス

要素をキーと値のペアとしてマップに挿入することを見てきましたが、マップ内の個々の要素にアクセスするにはどうすればよいでしょうか?これを実現するために、インデックス作成 を使用できます 、つまり、キーをインデックスとして提供します。

cout << element['x'] << '\n';

指定されたインデックスと同じ値を持つキーが存在する場合、そのキーに格納されている値が返されます。

もう 1 つの方法は、イテレータ を使用することです。 、今日のトピックで学びます。

マップ内のイテレータ関数

イテレータ関数は関数です イテレータを返す コレクション型のデータ構造の。これらの関数を使用すると、そのようなデータ構造を簡単にナビゲートできます。また、そのようなデータ構造で特定のデータを見つける機能も提供します。

iterator 制限された型の単なるポインタです コレクションのデータ構造上の特定の場所を指しています。反復子はコレクションに対してのみ存在し、個々のデータ型に対しては存在しません。

マップでは、反復子は特定の pair を指します 二分探索木に保存されたデータ構造 、マップ内。

注:イテレータは単なるポインタであり、イテレータを見つけて返す方法はデータ構造のタイプに依存します

c++ の地図 複数のイテレータ関数を提供します。今日説明するものは次のとおりです:

  • map::begin() 関数、
  • map::end() 関数

map::begin() 関数

map::begin() その名前が示すように、マップの先頭を指す反復子を返します。これにより、マップ内の最初の要素にアクセスできるようになり、マップ全体を横断するための開始点が提供されます。

例:

//Includes are not shown in this example

int main () {
    map<int, int> example;
    
    example[75] = 343;
    example[42] = 117;
    example[95] = 12;
    
    cout << "Map begins at key: " << example.begin()->first << '\n';
    cout << "Value stored at beginning of map: "
         << example.begin()->second
         << '\n';

    return 0;
}

上記のコードは、次の出力を生成します:

Map begins at key: 42
Value stored at beginning of map: 117

この関数を使用して、次のメソッド スキームを使用してマップ全体をトラバースできます。

int main () {
    // --Map initialization and insertion of values is same as the previous example-- //
    for (auto iter = example.begin(); iter != example.end(); i++) {
        cout << "Key: " << iter->first << " value: " << iter->second << '\n';
    }
    return 0;
}

example.begin() 変数 iter に割り当てられたマップの先頭を指すイテレータを返します . example.end() マップの最後に別のイテレータを返します。これについては、記事の後半で学習します。以降、iter は反復子であり、他のポインターと同じように動作することもできます。つまり、他のポインターと同じようにインクリメントおよびデクリメントできます。したがって、iter で for ループを開始します。 最初は example.begin に設定されています example.end() に達するまでインクリメントされます iter の各値に対して その値を出力します。

iter以降 特定の pair を指すポインタです マップでは、-> を使用する必要があります pair に格納されている値を参照する演算子 .

map::end() 関数

map::end() マップの最後に反復子を返します。これは、マップに値が含まれていないことを示しています。マップ内の要素を見つける必要がある場合に役立ちます。特定の要素が見つからない場合は、map::end() によって返されるイテレータを安全に返すことができます .

例:

前述の例で end 関数をそのように呼び出すと、

int main () {
    // --Map initialization and insertion of values is same as the previous example-- //
    cout << "Map ends at key: " << example.end()->first << '\n';
    cout << "Value stored at ending of map: "
         << example.end()->second
         << '\n';

    return 0;
}

次の出力を受け取ります。

Map ends at key: 3
Value stored at ending of map: 0

指定された反復子の位置にあるキーと値のペアの要素がマップに存在しないことがわかります。これは map::end() のためです マップの最後の要素を指すイテレータを返すのではなく、指定されたマップの外側の場所を返します。

これは、特定のマップで要素を見つける必要があるシナリオで非常に役立ちます。

例:

int main () {
    // --Map initialization and insertion of values is same as the previous example-- //
    
    // The key exists
    auto key_iterator = example.find(343);
    if (key_iterator != example.end()) {
        cout << "Key found with value: " key_iterator->second << '\n';
    }
    else {
        cout << "Key not found\n";
    }
    
    // The key does not exist
    key_iterator = example.find(900);
    if (key_iterator != example.end()) {
        cout << "Key found with value: " key_iterator->second << '\n';
    }
    else {
        cout << "Key not found\n";
    }
    return 0;
}

これにより、与えられた出力が生成されます:

Key found with value: 343
Key not found: 3

map::end() の場合 関数がマップに格納された最後の要素を指す反復子を返した場合、map::find() によって返された要素かどうかを確認するのは困難でした。 が見つからなかったか、マップの最後の要素でした。

では、マップの最後の要素を見つけるにはどうすればよいでしょうか。幸いなことに、map::end() を使用してマップの最後の要素を取得する方法が存在します。 .
仕組みを見てみましょう...

int main () {
    // --Map initialization and insertion of values is same as the previous example-- //
    
    // Print all the elements of the map
    for (auto iter:example) {
        cout << "Element with key: " << iter.first 
            << " is: " << iter.second 
            << '\n';
    }
    
    // Print the last element of the map using `map::end()`
    cout << "Last element of the map is: " 
        << (--example.end())->second
        << '\n';
    return 0;
}

次のコードの出力は、

Element with key: 42 is: 117
Element with key: 75 is: 343
Element with key: 95 is: 12
Last element of the map is: 12

ここで行ったことを分析しましょう。

  • まず、マップ全体を印刷して、基本的なトラバーサルによってマップの最後の要素を確認します。これは、実際のロジックの有効性を確認するために行われます。
  • では、map::end() を使用して最後の要素を出力するコードのこの部分を分析してみましょう。 、
    cout << "Last element of the map is: " 
        << (--example.end())->second
        << '\n';
  • ここに何かおかしいものがあります。(--example.end())->second とは何ですか? ?

前に学んだように、イテレータは単なる制限付きポインタです 、コレクションのデータ構造内の特定の場所を指します。つまり、イテレータを 1 だけデクリメントすると 手に持っていたイテレータの前に格納された要素の場所を取得できます。私たちは map::end() を知っています 1 の反復子を返します 最後の要素の位置よりも大きい場合、ポインターを 1 ステップ後方に移動し、マップに格納されている最後の要素にアクセスします。

結論

c++ のマップ またはその他の言語は、データを保存する優れた方法です。 API などの複数のサービスでデータを送信する場合に非常に役立つ、キーと値のペアの形式でデータを保存する機能を提供します。 .番号付きインデックスで値にアクセスする代わりに、適切なキーをインデックスとして使用できるため、コードが読みやすく機能的になります。 map::begin()map::end() 関数を使用すると、マップ内を簡単にナビゲートしたり検索したりできるため、マップの使用がさらに簡単になります。 2つだけでも 地図で利用できるそのような多くの機能のうち、それらはまだ開始するのに十分な基本機能を提供します.

OpenGenus のこの記事を読むと、C++ STL の map::begin と map::end の完全なアイデアが得られます。