繁体   English   中英

我 go 将如何比较向量与自身,并根据比较 function 删除元素?

[英]How would I go about comparing a vector with itself, and removing elements according to a comparison function?

我有一个向量v ,我想将其与其他所有元素进行比较。 为了简单起见,在我的示例中,向量由整数组成,比较 function 只是if (el1 == el2) 因此, std::unique将不起作用,因为我的真实列表包含一些数据结构。

下面是我迄今为止尝试过的示例,但它并没有按预期删除所有重复元素。

#include <iostream> 
#include <vector> 
#include <algorithm> 

bool CompareElements(int el1, int el2)
{
    if (el1 == el2) { // Just as an example
        return true;
    } else {
        return false;  
    }
}

int main() 
{ 
    std::vector<int> v = {4, 1, 3, 2, 2, 3, 6, 2, 3, 1, 4, 3, 2, 3, 5, 6, 5}; 

    // Should remove el1 if CompareElements() returns true.
    v.erase( 
        std::remove_if(v.begin(), v.end(), [&](int el1)
        { 
            bool result = false;
            std::for_each(v.begin(), v.end(), [&](int el2) 
            {   
                result = CompareElements(el1, el2);
            });
            return result;
        }), 
        v.end()
    );

    // Print the contents of v
    std::cout << "v = {";
    for (auto el : v) 
       std::cout << el << ", ";
    std::cout << "}\n"; 

    return 0; 
}

重申一下, std::unique或其任何变体在这里不起作用,因为我试图让它与自定义数据结构的向量一起工作,并且简单的重复删除器在我的实际程序中不起作用,因此使用用户定义的比较器。 删除的顺序无关紧要,我只是想从v中删除一个被比较的元素,这样该特定元素就不会与其他任何元素进行比较。

我期望的是像

v = {1, 4, 2, 3, 6, 5}

但是相反,我得到

v = {4, 1, 3, 2, 2, 3, 6, 2, 3, 1, 4, 3, 2, 3, 6, }

任何帮助或指示(明白了吗?)将不胜感激!

std::unique接受自定义二进制谓词。 因此,如果您为它提供您已经制作的自定义 function,std::unique 将起作用。

#include <iostream> 
#include <vector> 
#include <algorithm> 

int main() 
{ 
    std::vector<int> v = {4, 1, 3, 2, 2, 3, 6, 2, 3, 1, 4, 3, 2, 3, 5, 6, 5}; 
    v.erase(std::unique(v.begin(), v.end(), [](const int a, const int b)
        {
            return a == b;
        }), v.end());

    // Print the contents of v
    std::cout << "v = {";
    for (auto el : v) 
       std::cout << el << ", ";
    std::cout << "}\n"; 

    return 0; 
}

如果您提供的类型具有已实现的operator== ,它也可以工作。

struct Data
{
    Data(int _param)
        : m_Data{_param}
    {}

    int m_Data{};
    
    bool operator==(const Data& other) const
    {
        return m_Data == other.m_Data;
    }
};

int main()
{
    std::vector<Data> a{ 0,1,1,1,2,3,4,5 };

    a.erase(std::unique(a.begin(), a.end()), a.end());

    for (auto i : a)
        std::cout << i.m_Data << ", ";

    return 0;
}

如果时间复杂度对您来说不是什么大问题,您可以将向量转换为集合,然后再转换回向量。 该集合将删除重复项,您应该保留唯一值。

v=vector<struct>(set<struct>(v.begin(), v.end()));

我相信语法是如此或非常相似。

编辑:有评论说这是错误的。 Set 可以替换为 unordered_set 以消除排序效果,尽管我不确定 vector->set->vector 转换,需要检查。 但是,如果不支持转换,您仍然可以循环遍历集合并自行构造向量。

总之,你应该能够做到这一点:

set<struct> st=set<struct>(v.begin(), v.end());
vector<struct> uniqvec=vector<struct>(st.begin(), st.end())

如果排序很重要,据我所知,将set<struct>更改为unordered_set<struct>应该有效。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM