C++
 Computer >> コンピューター >  >> プログラミング >> C++

C++のSTL関数が返すポインタからインデックスを計算する方法

本記事では、C++においてSTL関数が返すポインタ(イテレータ)からインデックスを求める方法を詳しく解説します。

C++には、目的の要素が格納されているメモリ上のアドレスを指すポインタを返す組み込み関数が数多く存在します。しかし、これらの関数が返すのはあくまでメモリ上の位置であり、コンテナ内での実際のインデックスとは直接対応していません。

典型的な例がstd::max_element()関数です。この関数はコンテナ内の最大要素を検索できますが、戻り値として返すのはその要素のインデックスではなく、メモリ上のアドレス(イテレータ)です。場合によっては、このアドレスからインデックスを取得したい場面があります。ここでは、その具体的な手法を2つ紹介します。

方法1:先頭イテレータとの減算

最もシンプルな方法は、container.begin()メソッドで取得できる先頭位置のアドレスを利用することです。返されたアドレスから先頭アドレスを減算すると、その差分=インデックスを求めることができます。

これは、ランダムアクセスイテレータ(vectorなど)がポインタのように減算をサポートしているため実現できるテクニックです。

サンプルコード

#include <bits/stdc++.h>
using namespace std;
int main(){
    vector<int> vec = { 10, 40, 50, 60, 30};
    cout << "Max element is : " << (*max_element(vec.begin(), vec.end())) << endl;
    cout << "The index of maximum element : ";
    cout << max_element(vec.begin(), vec.end()) - vec.begin();
}

実行結果

Max element is : 60
The index of maximum element : 3

この例では、最大値「60」の位置がベクターの先頭から3番目であるため、インデックス「3」が出力されます。

方法2:std::distance()を使用する

もう一つの方法として、std::distance()関数を使う方法があります。この関数は、2つのイテレータ間の距離(要素数)を計算してくれるため、減算と同様にインデックスを求められます。

std::distance()の利点は、listやsetのような双方向イテレータしか持たないコンテナでも動作する点です(ただし、その場合は線形時間O(n)で計算される点に注意が必要です)。

サンプルコード

#include <bits/stdc++.h>
using namespace std;
int main(){
    vector<int> vec = { 10, 40, 50, 60, 30};
    cout << "Max element is : " << (*max_element(vec.begin(), vec.end())) << endl;
    cout << "The index of maximum element : ";
    cout << distance(vec.begin(), max_element(vec.begin(),
    vec.end()));
}

実行結果

Max element is : 60
The index of maximum element : 3

まとめ

STL関数が返すイテレータからインデックスを取得するには、以下の2つの方法が有効です。

  • begin()との減算:vectorなどのランダムアクセスイテレータ向け。定数時間O(1)で計算可能。
  • std::distance()の使用:より汎用的で、listやsetなどにも対応。ただしコンテナの種類によっては計算量が増える。

用途や使用しているコンテナの種類に応じて、適切な方法を選択しましょう。

  1. C++のSTLを使って配列が回文かどうかを判定するプログラム

    整数 n 個からなる配列 arr[n] が与えられたとき、「その配列は回文(パリンドローム)か?」を判定するのが本稿のテーマです。C++ の STL(標準テンプレートライブラリ)を活用して、この問題をシンプルに解いていきます。 STLとは STL(Standard Template Library)は、C++ に用意されたテンプレートクラスの集合体で、スタック・キュー・リストといったデータ構造や、ソート・反転などの便利な関数を提供します。これらを活用するには、テンプレートクラスに関する基本的な知識が必要です。本稿では、STL の reverse() 関数を使って配列を反転させています。 回文と

  2. C++のSTLを活用したBFS(幅優先探索)の実装方法 ― 競技プログラミング向け解説

    幅優先探索(BFS:Breadth First Search)は、与えられたグラフ上のすべてのノードを訪問するための基本的なアルゴリズムです。まず1つのノードを選択し、そこに隣接するノードを順番に訪問していきます。すべての隣接頂点の処理が完了したら、次の頂点へ移動し、同様にその隣接頂点を確認していく、という流れで探索を進めます。 競技プログラミングでは、いかに速く問題を解けるかが重要になります。C++のSTL(標準ライブラリ)を活用すれば、BFSを効率的に実装できます。その際に必要となるのがキュー(Queue)というデータ構造です。隣接するすべての頂点をキューに追加し、それらの処理が終わっ