2012-07-05 75 views
1

刷新问题 - 问题重新编写 - 我有一个需求,我需要用一个新的键和值替换一个对。考虑这个 -如何在std multimap中替换<key, value>

#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

诀窍是先行垫付的迭代器,然后删除迭代器的副本。

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)); 
} 

顺便说一句,因为这个代码是增加每次的关键,它会一遍又一遍的处理每一个元素。

+0

不错,我喜欢这个! – 2012-07-06 03:54:33

+0

许多非常感谢!这种技术适用于这个问题以及我更大的问题。 – tyrion 2012-07-06 04:32:45

+0

我添加了行键=键+10,因为我想证明我的新密钥是基于旧密钥的。事实上,新密钥是通过在不同的数据结构中查找旧密钥而获得的。 – tyrion 2012-07-06 04:40:17

2

如果擦除迭代器所在的条目,则指向其他multimap的所有链接都可能丢失。

(新)解决方案:

只需执行“擦除”你插入新的项目后:

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); 
+0

哦,等等,在简化我的大问题的过程中,我似乎要求给出错误的例子。我会编辑我的问题一点... – tyrion 2012-07-05 12:06:38

+0

但我看到了不同之处 - 您是否尝试了上述方法? – 2012-07-05 12:38:41

+0

我尝试了以上。它适用于更改值,但在我的情况下,我也需要更改密钥。 – tyrion 2012-07-05 13:48:59

相关问题