查找与输入数组交集最大的数组的有效方法

时间:2019-06-04 07:17:11

标签: algorithm sorting optimization similarity nearest-neighbor

说我有一大套数组(可以达到数百万个大小),并且我想确定(最好是精确的,尽管大约是可以的)该集合中与输入的交点最大的数组是什么?将是最有效的方法吗?我将列出一些解决方案,这些解决方案将其归结为另一个问题,但这些问题却在我的脑海中浮出水面,但我不确定它们是否一定是最好的。

这组数组可以存储在任何数据结构中,并且可以以任何方式对数组进行排序和存储。这个想法是在这里优化查询时间。

示例:说我的一组数组是(为方便起见,以基数排序,可以以任何选择的方式排序):

[('a', 'b'), ('a', 'e', 'f'), ('b', 'f', 'g'), ('b', 'j', 'z'), ('d', 'l', 'f'), ('x', 'y', 'z')]

我的输入数组是:

('a', 'f')

然后各个交叉点是:

[('a'), ('a', 'f'), ('f'), (), ('f'), ()]

因此,输出将是('a', 'f'),具有最大的2交集。作为奖励,最好拥有其中最大的K,因此在这里,如果K = 3 ,输出将是(以任何顺序):

[('a', 'f'), ('f'), ('a')]

我想到的一些可能的解决方案:

  • 我的域的大小受到限制,(例如a-z或 数字1-70等),因此我可以将它们表示为二进制 弦,现在的挑战是寻找最小的汉明顿 距离,我现在可以使用位置哈希来做些什么?例如,('a', 'f')可以表示为10000100000000000000000000
  • 还可以使用域受限制的事实,我可以创建一些 倒排索引,其中域中的项目指向不同的 数组中的数组,然后与输入数组中每个项目的这些结果相交(至少其中一些)-尽管我感觉像这样 效率会非常低(尤其是如果相交处转弯 很小)-与Google搜索的工作方式类似,尽管我不知道其算法的完整细节

谢谢您的正确回答或指导!

2 个答案:

答案 0 :(得分:2)

由于缺乏声誉,我无法通过评论事先提出一些问题:

  1. 所有数组都是唯一的,但是每个数组本身都是集合吗?
  2. 如果一个以上的数组共享最大的交集,是否需要全部列出?
  3. 您的输入可能比给定的最长数组更长?

迭代

没有散列集,我将按长度对数组进行排序,并从最长的数组开始,以通过找到仅大于或等于较短的数组大小的交集大小来最终跳过较短的数组。

如果您还对数组本身进行排序,则可以利用Hammington距离,但是不必同时对所有数组进行排序和转换,而只需从它们的一部分开始。如果您不使用Hammington,请记住,如果将输入与输入为大小+ 1的数组进行比较,则只需要进行比较,直到达到第一个比较时输入的最后一个元素小于当前数组即可元素。

  

a f

     

a c k z // //由于k> f,我们不需要比较f和z

我认为这种方式归结为O(n lg n)的复杂性,因为按大小对数组进行排序将是O(n lg n),计算大小n * O(1)并进行内部基数运算排序O(n)。比较本身就是O(n lg n)(对此不太确定),所以总数将是O(n lg n)* 2 + 2 * O(n)=> O(n lg n)。

一个简单的主意:您可以使用Radix对所有数组进行排序并将其转换为Hemmington,然后在其中填充一棵树并遍历它,直到没有进一步遍历会导致更小的距离为止。我不知道这有多有效。

https://stackoverflow.com/a/6390606/9758920

答案 1 :(得分:0)

我建议使用哈希集的简单方法。
如果哈希集实现良好且具有良好的哈希函数,则可以考虑在O(1)中检查元素是否属于此集合。
然后,我们可以执行以下操作:

function find_closest_arrays(A, B_1, ..., B_n) {
    result = [0, ..., 0] // array of size n
    for elem in A {
        for i in 1 ... n {
            if elem is in B_i {
                result[i] ++
            }
        }
    }
    return result
}

此函数返回一个数组resultresult[i]包含输入数组AB_i之间共有的元素数。
从这里开始,k的最佳表现是很快的,您要做的就是获取k中最大的result的索引。
此算法的时间复杂度为O(n * m),其中m是输入数组的大小,而n是数组集的大小。