单独保留重复元素

Keep duplicate elements separately

本文关键字:元素 保留 单独      更新时间:2023-10-16

我有一个包含大量城市名称的std::vector<std::string>textLines。我通过以下方式删除重复项:

using namespace std;
vector<string>::iterator iter;
sort(textLines.begin(), textLines.end());
iter = unique(textLines.begin(), textLines.end());

此时,重复元素都是向量末尾的空(空)字符串,大小与unique()之前相同。

我用以下命令删除它们:

textLines.resize(distance(textLines.begin(), iter));

这工作正常,但是有没有办法保留已删除的重复项?如果重复项只是移动到末尾而不是被空字符串替换,那会更好(对我来说)。

新的端由iter指出,从unique()返回,因此找到向量的新端没有问题。

换句话说,我想知道哪些行有重复,哪些没有。

你可以非常简单地做到这一点,而不必真正彻底改变你的逻辑。 您可以将重复项存储在另一个容器中,该容器由传递给unique()的比较谓词捕获:

vector<string> duplicates;
auto iter = unique(textLines.begin(), textLines.end(), [&duplicates](auto& first, auto& second) -> bool {
if (first == second)
{
duplicates.push_back(second);
return true;
}
return false;
});

活生生的例子:这里。

使用此解决方案,您需要额外的内存来存储元素计数。

vector<string>::iterator iter;
vector<string> v{ "a", "b", "a", "t", "a", "g", "t" };
sort(v.begin(), v.end());
// Find number of distinct elements
int count = 1;
auto current = v.cbegin();
for (auto i = v.cbegin() + 1; i < v.cend(); ++i) {
if (*i != *current) {
++count;
current = i;
}
}
// Count every entry
vector<int> vCount(count);
auto currentCount = vCount.begin();
++*currentCount;
for (size_t i = 1; i < v.size(); ++i) {
if (v[i] == v[i-1]) ++*currentCount;
else *++currentCount = 1;
}
iter = unique(v.begin(), v.end());

您始终可以编写自己的函数,这对于您有特定请求的情况是可取的。像这样:

//Define a "bool has(const vector &v, int element)" function before
vector<string> nonDuplicates;
vector<string> duplicates;
for (auto i : textList) {
if (has(nonDupicates, i)) {
duplicates.push(i);
}
else {
nonDuplicates.push(i);
}
}

这不是一种非常优雅或快速的方法,所以你可能会找到更好的方法,但如果你这样做,请使用 has() 的二进制搜索,如果你已经排序了它