Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 匹配整数数组(指纹)的算法_Algorithm - Fatal编程技术网

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

Algorithm 匹配整数数组(指纹)的算法,algorithm,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 for(int i=0;i<array2.length();i++) { for(int j=0;j<array1.length();j++) {

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

参考:

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
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]+" ");
       }
    }
}
//澄清 我对寻找连续的比赛感兴趣。在现实世界的例子中,会有很多奇异匹配(噪声)和可能1到3个更大的簇


参考文献和候选文献是文本(如书籍)的近似值(指纹)。小范围的比赛毫无意义。指纹中的值是K-gram的散列,因此值不是唯一的。

看起来您需要的是两个列表的组合。

只需从其中一个列表开始即可。弹出一个值,逐个将其与其他数组值进行比较,直到结束。并弹出另一个值进行检查,依此类推

因为两个序列都没有排序,所以您必须单独检查每个vaue。此java代码将提供所需的输出:

01 02 03 09 0A 0B 0C 0D 0E
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]+" ");
       }
    }
}
for(int i=0;i
注意:您在评论中说过数组从不排序。我认为这意味着您不是在寻找最长的公共子序列,而是想确定候选数组中的哪些元素也存在于引用数组中,而不考虑顺序(即集合交集).如果这不正确,请澄清问题

您可以在O(n+m)时间内完成这项工作,其中n和m是列表的长度。这比简单的方法要快得多,即遍历第一个列表并检查每个元素是否包含在第二个列表中

根据您的示例,我假设您的引用数组不包含重复项。如果它包含重复项,则有一些方法可以解决此问题,但您希望输出的外观并不完全清楚

最好的方法是构造一个位字段,这是一个数据结构,告诉你是否有任何给定的元素存在,它用一个位表示每个可能的元素。因此,你可以使用一个
int
来表示32个不同的输入/输出值。有一个实现可以直接使用走开

然后,解决问题的方法是遍历引用数组,将其每个元素放入位字段中。一旦完成此操作,您就有效地拥有了一个
,并且您可以通过查看其位是否在位字段中设置来测试任何给定值是否在引用数组中。因此,现在您可以遍历我们的候选数组,对于每个元素,测试其在位字段中的存在

即使可能值的范围很大,也可以这样做。即使允许所有可能的
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");
如果引用数组中没有重复项,当然可以使用
布尔[]


这比其他建议的方法(O(n*m)快得多。

两种整数序列都是按递增/递减顺序排序的吗?哦,对不起,这个例子可能会让人困惑。序列从不排序。这本质上就是diff所做的(用8位标记替换行)处理行为良好的情况有很多启发式方法。当你说序列从不排序时,这就不清楚你是想要一个最长的公共子序列,还是只想找出两个数组共有的元素,而不管顺序如何。@MAK根据第一种解释回答;我已经回答了ac根据第二条,但最好是澄清(通过编辑问题,而不是在评论中)。您需要为构成匹配的最小序列长度定义规则。如果您不关心连续性,则可以通过将其中一个放入哈希表中,然后查看另一个进行比较来快速完成。同样的操作也可以使用key->position的哈希表来完成。我实际上已经完成了指纹识别用于书籍模糊匹配的g算法之前,您是将1与1进行比较,还是将1与多进行比较?谢谢您的回答。您分享了一些有用的想法,这些想法很有用,但我担心我的问题仍然令人困惑。对此我深表歉意。值不是唯一的。我对连续匹配的最大范围感兴趣。