map と multimap 解答ページ | Programming Place Plus C++編【標準ライブラリ】 第9章

トップページC++編

C++編で扱っている C++ は 2003年に登場した C++03 という、とても古いバージョンのものです。C++ はその後、C++11 -> C++14 -> C++17 -> C++20 と更新されており、今後も 3年ごとに更新されます。
なかでも C++11 での更新は非常に大きなものであり、これから C++ の学習を始めるのなら、C++11 よりも古いバージョンを対象にするべきではありません。特に事情がないなら、新しい C++ を学んでください。 当サイトでは、C++14 をベースにした新C++編を作成中です。

問題①

問題① map/multimap に、特定のキーを持つ要素があるかどうか調べる関数を作成してください。map/multimap のテンプレート実引数は、任意で決めて構いません。


map において、[]演算子を使うと、要素がないと自動的に生成してしまうので、存在を確認する用途に使うのは不適切です。ここでは、findメンバ関数を使うのが妥当な選択です。

#include <iostream>
#include <map>
#include <string>

typedef std::map<std::string, int> StringIntMap;

bool FindMap(const StringIntMap& map, const StringIntMap::key_type& key)
{
    return map.find(key) != map.end();
}

int main()
{
    const std::pair<std::string, int> a[] = {
        std::make_pair("aaa", 0),
        std::make_pair("bbb", 1),
        std::make_pair("ccc", 2),
    };

    StringIntMap siMap(a, a + 3);

    std::cout << std::boolalpha
              << FindMap(siMap, "bbb") << "\n"
              << FindMap(siMap, "xyz") << std::endl;
}

実行結果

true
false

問題②

問題② map に登録されている要素のキーを変更する関数を作成してください。指定されたキーを持った要素がない場合は、新規の要素が作られるものとします。


本編に書いているように、キーを書き換えることは許されていません。どうしても必要であれば、いったん、要素を削除した後、新しいキーを使って挿入し直すしかありません。

#include <iostream>
#include <map>
#include <string>

typedef std::map<std::string, int> StringIntMap;

void ReplaceMapKey(StringIntMap& siMap, const StringIntMap::key_type& oldKey, const StringIntMap::key_type& newKey)
{
    const StringIntMap::iterator it = siMap.find(oldKey);
    if (it != siMap.end()) {
        const StringIntMap::mapped_type value = it->second;
        siMap.erase(it);
        siMap.insert(std::make_pair(newKey, value));
    }
    else {
        siMap.insert(std::make_pair(newKey, StringIntMap::mapped_type()));
    }
}

void PrintStringIntMap(const StringIntMap& siMap)
{
    const StringIntMap::const_iterator itEnd = siMap.end();
    for (StringIntMap::const_iterator it = siMap.begin(); it != itEnd; ++it) {
        std::cout << it->first << ":" << it->second << " ";
    }
    std::cout << std::endl;
}

int main()
{
    const std::pair<std::string, int> a[] = {
        std::make_pair("aaa", 0),
        std::make_pair("bbb", 1),
        std::make_pair("ccc", 2),
    };

    StringIntMap siMap(a, a + 3);

    ReplaceMapKey(siMap, "bbb", "xyz");
    ReplaceMapKey(siMap, "abc", "ABC");

    PrintStringIntMap(siMap);
}

実行結果

ABC:0 aaa:0 ccc:2 xyz:1

まず、findメンバ関数を使って、要素がすでにあるかどうかを確認します。後でイテレータを使うので、問題①で作った bool値しか返さない関数ではなく、find を使います。

すでに要素があるのなら、要素の値を保存してから、eraseメンバ関数でいったん要素を削除します。そして、新しいキーと、保存しておいた要素の値の pair を、insertメンバ関数で再登録します。要素がなかったのなら、要素をデフォルトコンストラクタで生成して、挿入します。


参考リンク


更新履歴

’2015/10/3 新規作成。



第9章のメインページへ

C++編のトップページへ

Programming Place Plus のトップページへ



はてなブックマーク に保存 Pocket に保存 Facebook でシェア
X で ポストフォロー LINE で送る noteで書く
rss1.0 取得ボタン RSS 管理者情報 プライバシーポリシー
先頭へ戻る