单独保留重复元素

时间:2018-02-13 12:30:40

标签: c++

我有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()指出了新的结尾,因此找到向量的新结尾没有问题。

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

3 个答案:

答案 0 :(得分:5)

您可以非常简单地执行此操作,而无需实际更改逻辑。 您可以将重复项存储在另一个容器中,该容器由传递给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;
});

实例:here

答案 1 :(得分:0)

您可以随时编写自己的功能,对于像您这样的具有特定请求的情况,建议使用此功能。类似的东西:

//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(),如果你已经对它进行了排序

答案 2 :(得分:0)

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

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