[C++]std:mapの使い方

C++で連想配列を使用するにはSTLのstd::mapを使用します。

この記事では、std::mapの基本的な使い方を解説します。

準備

std::mapを使うためには、mapをincludeします。

C++
// std::mapを使うために必要なファイル
#include <map>

毎回std::mapと記述するのが面倒な場合には、includeの後に以下の一文を記載することでstd名前空間を省略することができるようになります。

C++
using namespace std;

以降この記事では、std名前空間は省略して全てmapで統一します。

変数宣言

map型の変数を宣言する際には、以下のように書きます。

C++
// キーがstring型、値がint型の連想配列
map<string, int> data;

この時、mapの後の<>の間に挟んだ型の1つ目の型をキー、2つ目の型を値とした連想配列となります。

データの追加

map型変数にデータの追加を行う場合には、通常の配列のように[]を使用します。

C++
// データを追加
data["apple"] = 100;

指定したキーがmap型変数の中に存在しない場合にはデータの追加となり、すでに存在している場合にはデータの上書きとなります。

データの削除

map型変数からデータの削除を行う場合にはerase関数を使用します。

C++
// 指定したキーのデータを削除
data.erase("apple");

削除したいキーをerase関数に渡すことで、該当キーのデータが存在する場合そのデータを削除します。

また、全てのデータを一括削除する場合にはclear関数を使用します。

C++
// データの一括削除
data.clear();

データへアクセス

map型変数のデータにアクセスする場合には、通常の配列と同じように[]を指定します。

C++
// appleのデータを取得
int apple = data["apple"];
// orangeのデータを取得
int orange = data["orange"];

また、map型変数がconst型の場合にはat関数を使用して変数値の取得を行うことも可能です。

C++
// appleのデータを取得
int apple = data.at("apple");

forループ

map型変数のデータのforループは、イテレータで行います。

C++
// イテレータによるループ
for(map<string, int>::iterator itr = data.begin(); itr != data.end(); ++itr)
{
    // 処理(下例ではキーと値を出力)
    cout << "Key: " << itr->first << ", Value: " << itr->second << endl;
}

ループ変数のイテレータからは、firstでキーを、secondで値を取得することができます。

また、C++11以降では以下のようにループ変数の宣言を置き換えることも可能です。

C++11
// イテレータによるループ
for(auto itr = data.begin(); itr != data.end(); ++itr)
{
    // 処理
}

さらに、C++14以降では範囲for文を使って以下のように書き換えることも可能です。

C++14
// 範囲for文によるループ
for(auto& d : data)
{
    // 処理
}

お試しコード

ここまででざっとmapの基本的な使い方についての解説を行いました。

これらを使って「1〜5までの乱数を100個生成後、生成された乱数のヒストグラムを作成する」プログラムを書いてみます。

C++
#include <iostream>
#include <map>
#include <cstdlib>
#include <ctime>
using namespace std;

int main()
{
    int data[100];
    map<int, int> hist;

    // 乱数シード初期化
    ::srand((unsigned)::time(NULL));
    // 1〜5までの乱数を100個生成
    for(int idx = 0; idx < 100; idx++)
    {
        data[idx] = rand() % 5 + 1;
    }

    // ヒストグラム生成
    for(int idx = 0; idx < 100; idx++)
    {
        hist[data[idx]]++;
    }

    // ヒストグラム出力
    for(auto h : hist)
    {
        cout << h.first << ": " << h.second << endl;
    }

    return 0;
}

上記のプログラムを実行すると、1〜5までの乱数のヒストグラム(頻度分布)が出力されます。

試しに私の環境で実行した結果は以下の通りです。

1: 17
2: 16
3: 24
4: 23
5: 20

データに多少ばらつきはありますが、概ね理論値通りの20前後の出現率となりました。

 

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です