C ++从两个向量中删除重复的元素

时间:2015-12-08 00:56:33

标签: c++ vector duplicates

我有两个向量std::vector<double> xvecstd::vector<double> yvec,每个向量都有数百万个元素和相同的大小。但是xvec [i]和yvec [i]的组合用于定义一个唯一的对象。例如

xvec = {1.0,2.0,2.0,3.0,2.0}
yvec = {5.0,1.0,1.5,2.0,1.0}

然后2.0_1.0组合是重复元素,应该从x和y向量中删除。

我想在删除重复元素后返回xvec和yvec。按照示例,返回的xvec和yvec应为

xvec = {1.0,2.0,2.0,3.0}
yvec = {5.0,1.0,1.5,2.0}

我知道如何使用sort和unique函数为单个向量执行此类任务。但任何人都可以给我一些想法来完成这个算法?

2 个答案:

答案 0 :(得分:0)

我会看到三种可能性:

解决方案1 ​​

针对给定问题自行实施std::sortstd::uniquestd::unique很容易实现,但我现在不想实现排序算法。所以我不会向你展示一个例子。

解决方案2

实施您自己的RandomAccessIteratorForwardIterator并使用std::sortstd::unique

解决方案3

迭代值并使用std::setstd::unordered_set检查当前值是否已存在。

std::vector<double> xvec = {...};
std::vector<double> yvec = {...};

std::set<std::tuple<double,double> > set;
for (std::size_t i = 0; i < xvec.size();) {
    if (set.emplace(xvec[i], yvec[i]).second) {
        i++;
    } else {
        xvec.erase(xvec.begin() + i);
        yvec.erase(yvec.begin() + i);
    }
}

答案 1 :(得分:0)

您可以将xvecyvec存储为成对的矢量,即std::vector<std::pair<double,double> > vec,从而实现此目的。这样您就可以轻松使用std::sortstd::unique来实现您所描述的内容。我在下面列出了一些代码来说明这一点。

注意:下面的代码有点冗长,但通过在重复数据删除发生之前和之后打印每个元素来演示一个有效的解决方案。应使用标志--std=c++11

编译代码
#include <iostream>
#include <vector>
#include <algorithm>

int main()
{
    // Vector of pairs with duplicates.
    std::vector<std::pair<double,double> > vec = {{1,1},{1,3},{1,1},{2,4},{5,1}};

    std::cout << "Before:\n";
    // Prints x - values
    std::cout << "x:";
    for (auto i : vec)
    {
        std::cout << i.first << "\t";
    }
    std::cout << "\ny:";

    // Prints y - values
    for (auto i : vec)
    {
        std::cout << i.second << "\t";
    }
    std::cout << "\nAfter:\n";

    // The magic happens here :)
    std::sort(vec.begin(),vec.end());
    auto last = std::unique(vec.begin(), vec.end());
    vec.erase(last, vec.end());

    std::cout << "x:";
    // Prints x - values
    for (auto i : vec)
    {
        std::cout << i.first << "\t";
    }
    std::cout << "\ny:";
    // Prints y - values
    for (auto i : vec)
    {
        std::cout << i.second << "\t";
    }
    return 0;
}