1

質問の言い換え - 質問の言い換え - ペアを新しいキーと値に置き換える必要があるという要件があります。このことを考慮 -

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

using namespace std;

int main()
{
    std::multimap<unsigned int, std::string> mymap;

    mymap.insert(std::multimap<unsigned int, std::string>::value_type(0, "A1"));
    mymap.insert(std::multimap<unsigned int, std::string>::value_type(0, "A2"));
    mymap.insert(std::multimap<unsigned int, std::string>::value_type(2, "C1"));
    mymap.insert(std::multimap<unsigned int, std::string>::value_type(2, "C2"));
    mymap.insert(std::multimap<unsigned int, std::string>::value_type(1, "B1"));
    mymap.insert(std::multimap<unsigned int, std::string>::value_type(1, "B2"));
    mymap.insert(std::multimap<unsigned int, std::string>::value_type(1, "B3"));

    std::pair<std::multimap<unsigned int, std::string>::iterator, std::multimap<unsigned int, std::string>::iterator> pr = mymap.equal_range(1);

    std::multimap<unsigned int, std::string>::iterator it;
    for (it=pr.first; it!=pr.second; ++it)
    {
        unsigned int key = it->first;
    key = key+10;

        std::string val = it->second;
        val = "X" + val;
        mymap.erase(it);
        mymap.insert(std::multimap<unsigned int, std::string>::value_type(key, val));

    }

    for ( it=mymap.begin() ; it != mymap.end(); it++ )
    {
        cout << (*it).first << " => " << (*it).second << endl;
    }

    return 0;

}

イテレータが無効化されているため、Visual Studio 2008 でプログラムがクラッシュします。

私はそれが次のようになることを期待しています:

0 => A1
0 => A2
2 => C1
2 => C2
11 => XB1
11 => XB2
11 => XB3

アイデアは、マップ内の既存のエントリを新しいエントリに置き換えたいということです。

私は何を間違っていますか?どんな助けでも大歓迎です。

4

2 に答える 2

6

秘訣は、最初にイテレータを進めてから、イテレータのコピーを消去することです。

std::multimap<unsigned int, std::string>::iterator it = pr.first;
while (it != pr.second)
{
    unsigned int key = it->first;
    key = key+10;

    std::string val = it->second;
    val = "X" + val;

    std::multimap<unsigned int, std::string>::iterator itCopy = it;
    ++it;
    mymap.erase(itCopy);
    mymap.insert(std::multimap<unsigned int, std::string>::value_type(key, val));
}

C ++ 11では、次のことができます。

std::multimap<unsigned int, std::string>::iterator it = pr.first;
while (it != pr.second)
{
    unsigned int key = it->first;
    key = key+10;

    std::string val = it->second;
    val = "X" + val;

    it = mymap.erase(it);
    mymap.insert(std::multimap<unsigned int, std::string>::value_type(key, val));
}

ちなみに、このコードは毎回キーを増やしているので、すべての要素を何度も処理します。

于 2012-07-05T20:33:45.617 に答える
2

イテレータがあるエントリを消去すると、残りのマルチマップへのすべてのリンクが失われる可能性があります。

(新しい) 解決策:

新しいエントリを挿入した後、単に「消去」を実行します。

std::multimap<unsigned int, std::string>::iterator it;
for (it=pr.first; it!=pr.second; ++it)
{
    unsigned int key = it->first;
    key = key+10;

    std::string val = it->second;
    val = "X" + val;
    mymap.insert(std::multimap<unsigned int, std::string>::value_type(key, val));
}
mymap.erase(pr.first, pr.second);
于 2012-07-05T12:00:16.730 に答える