提问人:Lumpi 提问时间:1/20/2011 最后编辑:casablancaLumpi 更新时间:1/21/2011 访问量:1921
C++ 列表删除重复字符串
C++ list remove duplicates strings
问:
我在使用列表时遇到了一些问题。
我所拥有的:我正在阅读聊天框中的行,其中不时出现新的文本行。 我总是从盒子里取出最后 20 行,然后我想将它们与我之前取到的所有行进行比较。如果发现一条新生产线,它将被发送到外部功能,该外部功能将拆卸该生产线以进行进一步处理。在我使用数组和向量之前,但列表似乎是更好的方法。
我的想法:我有一个名为 usedlines 的列表,其中包含所有旧的 allready used 行。 列表 fetchedLines 包含从聊天框中获取的最新 20 行。
不,我只是想循环通过它们两个,以确定获取的行是否包含以前从未见过的新行。循环结束后,fetchedlines 中的剩余部分将处理到下一个函数。
问题:当我循环这个循环时,我过了一会儿会得到一个坏指针。为什么? 奖励:有没有人有更好的主意来解决这个任务?
typedef list<string> LISTSTR;
LISTSTR::iterator f;
LISTSTR::iterator u;
LISTSTR fetchedlines;
LISTSTR usedLines;
fetchedlines.insert(fetchedlines.end(), "one");
fetchedlines.push_back("two");
fetchedlines.push_back("three");
fetchedlines.push_back("four");
fetchedlines.push_back("three");
usedLines.push_back("three");
usedLines.push_back("blää");
usedLines.push_back("lumpi");
usedLines.push_back("four");
for (u = usedLines.begin(); u != usedLines.end(); u++)
{
for (f = fetchedlines.begin(); f != fetchedlines.end(); f++)
{
if(*u==*f)
fetchedlines.remove(*f);
}
}
答:
调用 使迭代器失效。fetchedlines.remove(*f)
编辑:
您遇到的问题的可能解决方案是迭代并删除其中包含的所有元素。usedLines
fetchedlines
for (u = usedLines.begin() u != usedLines.end(); u++)
fetchedLines.remove(*u);
//Process all of fetchedLines
评论
您正在从中删除一个元素,而您正在迭代它。fetchedlines
这就是为什么你得到一个糟糕的指针。
评论
因为 *f 是一个迭代器,指向您刚刚擦除的元素。
请尝试以下操作:
if(*u==*f)
{
LISTSTR::iterator t = f;;
f--;
fetchedlines.remove(*t);
}
顺便说一句,删除在列表中搜索与迭代器 f 指向的数据匹配的内容。如果你想简单地摆脱指向你的数据,你最好这样做
f = fetchedlines.erase( f );
f--;
出现错误的原因是 fetchedlines.remove (*f) 修改了 fetchedlines,如果它是最后一个元素,则 for 循环增量太大
试试这样的方法:
for (u = userLines.begin (); u != usedLines.end (); ++u)
{
for (f = fetchedlines.begin (); f != fetchedlines.end ();)
{
if (*u == *f)
{
f = fetchedlines.erase (f);
}
else
{
++f;
}
}
}
(当然,这并没有解决这是否是解决问题的好方法)
在循环访问列表(或几乎任何其他容器)时,绝不能修改它。这是你眼前的问题。
一个更有趣的问题是,你为什么一开始就这样做。有没有办法获得行上的序列号,或者时间戳,所以你可以比较它们?
评论
这可以通过 和 lambda 表达式来完成。此方法仍然是两个嵌套循环,但它们隐藏在函数调用中。对于小型列表来说,这可能足够快,但不能很好地扩展。如果对数据进行排序或使用订购的容器,则速度可能会快得多。list::remove_if
fetchedLines.remove_if([&](std::string &str)
{
return std::find(usedLines.begin(), usedLines.end(), str) != usedLines.end();
});
评论
std::set
std::remove_if
std::set_intersection