是否有任何标准算法可以对向量元素进行成对比较?

Posted

技术标签:

【中文标题】是否有任何标准算法可以对向量元素进行成对比较?【英文标题】:Is there any standard algorithm for doing pairwise comparison of Vector Elements? 【发布时间】:2013-08-31 11:33:16 【问题描述】:

我基本上有两个带有无序元素的向量,只能检查它们是否相等。有没有像 std::equal 这样的标准算法来比较所有 n^2 对并检查一个向量的所有元素是否都在另一个向量中?

【问题讨论】:

在 O(nlogn) 中排序并在 O(n) 中进行比较? 这可能是std::unordered_set 的工作。 @DyP:只能检查是否相等的无序元素听起来无法排序 @Jon 可能是。我不会想到无序容器支持==!=,但显然他们支持。最坏情况的复杂度是 O(n^2)(这就是为什么我没想到它会被支持),但在大多数情况下,您可能不会遇到最坏的情况。 @DavidRodríguez-dribeas 听起来是这样。另一方面,我认为我从未见过无法定义某种任意顺序的数据类型,这对于sort 来说已经足够了(即使它不符合任何逻辑顺序) . 【参考方案1】:

向量有多大?比如:

template <typename T>
bool
unorderedEqual( std::vector<T> const& v1, std::vector<T> const& v2 )

    return v1.size() == v2.size()
        && std::find_if(
            v1.begin(), v1.end(),
            [&v2]( T const& elem )  
                return std::find( v2.begin(), v2.end(), elem ) == v2.end();
             ) == v1.end();

可能会成功,但它是 O(n^2) (这意味着它只是好的 对于非常小的向量),如果向量 包含重复元素。 (请注意,我还没有测试过, 所以它可能包含拼写错误和其他错误。但是应该 足够接近以给出总体思路。)

否则,我认为您必须进行排序;即使物体 不支持小于,你应该能够定义一个 订购功能。 (顺序可以是任意的,没有 除了允许使用std::sort之外的意义。)

【讨论】:

对于重复,我猜你应该使用 std::count ?尽管如此,实际上使用侧面数据结构(如std::unordered_map&lt;T, size_t&gt; 来计算每个元素的出现次数)似乎很麻烦。【参考方案2】:

较大的向量最便宜的方法是最有可能对两者进行排序,然后测试是否相等

#include <vector>
#include <algorithm>

// ....

vector<yourType> v1;
vector<yourType> v2;

sort(v1);
sort(v2);
bool result = equal(begin(v1), end(v1), begin(v2));

【讨论】:

【参考方案3】:

假设您的向量包含数据,复制或交换的成本很高:

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

typedef std::vector<std::size_t> Index;
typedef std::vector<int> Data;
inline void init(Index& index, const Data& data) 

    struct Less
    
        const Data& data;

        Less(const Data& data)
        :   data(data)
        

        bool operator () (std::size_t a, std::size_t b) 
            return data[a] < data[b];
        
    ;

    index.reserve(data.size());
    for(size_t i = 0; i < data.size(); ++i) 
        index.push_back(i);
    
    Less less(data);
    std::sort(index.begin(), index.end(), less);


int main()

    Data d0  1, 0, 4, 2, 5, 3 ;
    Data d1  5, 2, 3, 0, 4, 1 ;

    if(d0.size() == d1.size()) 
        Index i0;
        Index i1;
        init(i0, d0);
        init(i1, d1);
        for(std::size_t i = 0; i < d0.size(); ++i) 
            std::cout << d0[i0[i]] << " == " << d1[i1[i]] << std::endl;
            if(d0[i0[i]] != d1[i1[i]]) 
                std::cout << "Not equal" << std::endl;
                return 1;
            
        
    
    std::cout << "Equal" << std::endl;
    return 0;

【讨论】:

以上是关于是否有任何标准算法可以对向量元素进行成对比较?的主要内容,如果未能解决你的问题,请参考以下文章

用于成对比较和跟踪最大/最长序列的 STL 算法

成对比较可以返回比 -1、0、+1 更多信息的排序算法

6.5-数据结构&算法-标准模板STL/STL容器/向量

向量排序算法,只对大于 0 的元素进行排序

容器和算法2

自定义聚类算法