C++ 删除C+中特定键的条目+;STL多重映射
我有这个示例代码来将条目插入到多重映射中。我正在尝试删除指定密钥的特定条目。但这段代码进入无限循环。有人能帮我处理这个代码吗C++ 删除C+中特定键的条目+;STL多重映射,c++,stl,C++,Stl,我有这个示例代码来将条目插入到多重映射中。我正在尝试删除指定密钥的特定条目。但这段代码进入无限循环。有人能帮我处理这个代码吗 #include <iostream> #include <map> #include <string> using namespace std; int main() { multimap<string, string> names; string n; names.insert(pair<
#include <iostream>
#include <map>
#include <string>
using namespace std;
int main()
{
multimap<string, string> names;
string n;
names.insert(pair<string, string>("Z", "F"));
names.insert(pair<string, string>("Z", "A"));
names.insert(pair<string, string>("S", "T"));
names.insert(pair<string, string>("S", "A"));
names.insert(pair<string, string>("S", "J"));
names.insert(pair<string, string>("D", "H"));
names.insert(pair<string, string>("D", "W"));
names.insert(pair<string, string>("D", "R"));
multimap<string, string>::iterator p;
p = names.find("Z");
if(p != names.end()) { // found a name
do {
cout << n << ", " << p->second;
cout << endl;
if (p->second.compare("A") == 0) {
names.erase(p);
p++;
} else {
p++;
}
} while (p != names.upper_bound("Z"));
}
else{
cout << "Name not found.\n";
}
p = names.find("Z");
if(p != names.end()) { // found a name
do {
cout << n << ", " << p->second;
cout << endl;
} while (p != names.upper_bound("Z"));
}
else{
cout << "Name not found.\n";
}
return 0;
}
#包括
#包括
#包括
使用名称空间std;
int main()
{
多重映射名称;
字符串n;
名称。插入(成对(“Z”、“F”);
名称。插入(成对(“Z”、“A”);
名称。插入(成对(“S”、“T”);
名称。插入(成对(“S”、“A”);
名称。插入(成对(“S”、“J”);
名称。插入(成对(“D”、“H”);
名称。插入(成对(“D”、“W”);
名称。插入(成对(“D”、“R”);
多重映射::迭代器p;
p=名称。查找(“Z”);
如果(p!=names.end()){//找到一个名称
做{
coutmultimap::erase
使所有指向erase元素的迭代器无效,因此
names.erase(p);
p++;
擦除p,从而使其无效,然后尝试递增无效迭代器。您可以通过将p
复制到一个临时递增p,然后擦除临时迭代器来修复此问题
multimap<string, string>::iterator temp = p;
++p;
names.erase(temp);
编辑:以上事实上并不是无限循环的来源。在第二个循环中,你不会增加p
,所以它永远都会存在。但是,这仍然是你应该解决的问题,因为它可能会导致无法预测的错误,并且很难追踪到错误。正如其他人所说,推进一个指向刚刚被删除的元素的迭代器是一种错误不保证工作。您可以改为使用后缀++
运算符检索已擦除元素后面的元素的迭代器,然后再将其擦除:
在C++11中,您也可以检索erase
的返回值,该值指向以下元素(如果没有更多元素,则为end()
):
也有人说过,根据定义,第二个循环是无限循环,因为它从不增加计数器
但是,还有一件事需要说明:检查元素范围中的最后一个元素是否已到达的方法不是很有效:在循环的每次迭代中调用upper_-bound
,这将每次导致新的O(log(n))树搜索,尽管返回的迭代器始终相同
通过在进入循环并存储结果之前运行upper\u-bound
显然可以改善这一点。但更好的是,我建议您运行equal\u-range
函数一次,然后简单地遍历它返回的范围:
typedef multimap<string,string>::const_iterator mapit;
std::pair<mapit,mapit> range = names.equal_range("Z");
mapit it = range.first;
while (it != range.second)
if (it->second == "A")
names.erase(it++);
else
++it;
typedef多重映射::常量迭代器mapit;
std::pair range=name.equal_range(“Z”);
mapit it=range.first;
while(it!=范围秒)
如果(它->秒==“A”)
名称。擦除(it++);
其他的
++它;
在C++11中,使用auto
会使它看起来更好。@dbrown,如何解决此问题?我尝试将迭代器复制到临时迭代器,并使用该临时迭代器进行擦除,但无效
names.erase(p++);
p = names.erase(p);
typedef multimap<string,string>::const_iterator mapit;
std::pair<mapit,mapit> range = names.equal_range("Z");
mapit it = range.first;
while (it != range.second)
if (it->second == "A")
names.erase(it++);
else
++it;