Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/tfs/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 删除C+中特定键的条目+;STL多重映射_C++_Stl - Fatal编程技术网

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()){//找到一个名称
做{

cout
multimap::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;