匹配整数数组的算法(指纹)

时间:2014-10-16 22:35:41

标签: algorithm

我正在寻找一种匹配两个整数数组的算法。例如:

参考:

00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

候选:

FF FF FF 01 02 03 FF AA 09 0A 0B 0C 0D 0E FF

期望的输出:

01 02 03 09 0A 0B 0C 0D 0E

//澄清 我有兴趣找到连续的比赛。在现实世界的例子中,会有很多单一的匹配(噪音),也许还有1到3个更大的集群。

参考和候选人是文本的近似值(指纹)(如书)。小范围的比赛毫无意义。指纹内的值是K-Grams的哈希值,因此值不是唯一的。

4 个答案:

答案 0 :(得分:2)

看起来你需要的是两个列表的Longest Common Subsequence

答案 1 :(得分:1)

只需从其中一个开始即可。弹出一个值,将其与其他数组值逐个进行比较,直到它结束。并弹出另一个值来检查,等等......!

答案 2 :(得分:1)

  

注意:您在评论中说数组永远不会排序。我认为这意味着您不是在寻找最长的公共子序列,而只是想要确定候选阵列中的哪些元素也存在于参考数组中,无论顺序如何(即一组交集)。如果这不对,请澄清问题!

您可以在O(n + m)时间内执行此操作,其中n和m是列表的长度。这比通过第一个列表和检查每个元素的天真方法快得多,它是否包含在第二个列表中。

我假设,从您的示例中,您的参考数组不包含重复项。如果有的话,有办法解决这个问题,但是那时你的输出看起来并不完全清楚。

执行此操作的豪华方法是构造一个位字段,这是一个数据结构,告诉您是否存在任何给定元素,并且它使用单个位表示每个可能的元素。因此,您可以使用单个int来表示32个不同的输入/输出值。有Apache Commons实施可供您直接使用。

解决问题的方法是通过参考数组,将其中的每个元素放入位字段。完成此操作后,您实际上拥有Set,并且您可以针对任何给定值测试它是否在您的参考数组中,方法是查看其位是否在位字段中设置。所以现在你浏览你的候选数组,并为每个元素测试它在bit字段中的存在。

即使可能值的范围很大,您仍然可以这样做。即使允许所有可能的int值,您仍然可以在1GB内存中表示所有这些值。

从您的示例看,好像可能值的数量很小,在这种情况下,您可以更简单地执行此操作,并且还可以处理重复项,只需拥有int[]数组,每个可能的值一个。因此,如果值的范围是0到999,那么您声明

int[] present = new int[1000];

然后你浏览你的参考数组:

for (int ref: refArray)
    present[ref]++;

现在,您可以计算present数组中每个值的出现次数。您浏览候选数组,并查找每个数组中present数组中的数量:

for (int cand: candidateArray)
    if (present[cand]>0)
        System.out.println(cand+" occurred "+present[cand]+" times in the ref array");

如果您在参考数组中没有获得重复项,那么当然可以使用boolean[]

比其他建议的方式更快,这是O(n * m)。

答案 3 :(得分:0)

由于两个序列都没有排序,您必须单独检查每个vaue。这个java代码将提供您想要的输出:

for(int i=0;i<array2.length();i++)
{
    for(int j=0;j<array1.length();j++)
    {
       if(array1[j].equals(array2[i])
       {
           System.out.println(array2[i]+" ");
       }
    }
}
相关问题