3

コンテナに頭痛の種がありstd::multimap、目標を達成するための適切な方法を知りたいと思います。基本的に、これが私のSSCCEです:

#include <iostream>
#include <map>

int main ()
{
    typedef std::multimap<int, int> CollectionType;
    typedef std::pair<CollectionType::iterator, CollectionType::iterator> RangeType;

    CollectionType multiMap;

    multiMap.insert(std::make_pair(1, 1));
    multiMap.insert(std::make_pair(1, 2));
    multiMap.insert(std::make_pair(2, 3));
    multiMap.insert(std::make_pair(2, 4));
    multiMap.insert(std::make_pair(2, 5));
    multiMap.insert(std::make_pair(3, 1));

    RangeType range = multiMap.equal_range(2);
    for (CollectionType::iterator iterator = range.first; iterator != range.second; ++iterator)
    {
        if (iterator->second == 4)
        {
            //multiMap.erase(iterator);//ISSUE 1
        }
        else
        {
            //iterator->first = -1;//ISSUE 2
        }
    }

    return 0;
}

上記のようにmultimap、特定のキーの範囲を選択してから、次のことを行う必要があります。

  1. 範囲から特定の行を消去する必要があります
  2. 範囲から他の行のキーを変更する必要があります

1については、「消去された要素への参照とイテレータが無効になっている」ので、どうすればそれらの要素を削除できますか?特定のイテレーターをいくつかのコンテナーにプッシュし、ループが終了したらそれを反復する必要がありますか?私はこの答えを見ましたが、それは少しハック/醜い/エラーが発生しやすい/などのようです...

2に関しては、「ダム」アプローチは(明らかに)機能しないので、私が必要とするものを達成するための良いアプローチは何でしょうか?問題1を解決したら、要素を削除してその場所に新しい要素を挿入できますが、削除したばかりのキーと同じキーを持つアイテムを誤って挿入した場合、反復が混乱する可能性はありませんか? ..

int second = iterator->second;
localEdges.smarter_erase(iterator);
localEdges.insert(std::make_pair(-1, second));
4

1 に答える 1

4

eraseイテレータを返すので、イテレータをそれにリセットすると、引き続き有効になります。

新しいキーで再挿入し、元のキーを消去するだけです

http://ideone.com/0Pr6Qc

#include <iostream>
#include <map>

void printMultimap(const std::multimap<int, int>& multiMap)
{
    std::cout << "MultiMap:\n";
    for (const auto& pair : multiMap)
    {
        std::cout << pair.first << ":" << pair.second << "\n";
    }
}

int main()
{
    std::multimap<int, int> multiMap;
    multiMap.insert(std::make_pair(1, 1));
    multiMap.insert(std::make_pair(1, 2));
    multiMap.insert(std::make_pair(2, 3));
    multiMap.insert(std::make_pair(2, 4));
    multiMap.insert(std::make_pair(2, 5));
    multiMap.insert(std::make_pair(3, 1));

    printMultimap(multiMap);

    auto range = multiMap.equal_range(2);
    for (auto iterator = range.first; iterator != range.second;)
    {
        if (iterator->second != 4)
        {
            multiMap.insert(std::make_pair(-1, iterator->second));
        }
        iterator = multiMap.erase(iterator);
    }

    printMultimap(multiMap);

    return 0;
}
于 2013-03-12T02:25:28.393 に答える