注意:如果您的评论说,阵列从未排序。我将这意味着你不是在寻找最长的公共子序列,而只是想确定候选数组中的哪些元素也出现在参考数组中,而不管其顺序如何(即一组交集)() 。如果这是不正确的,请澄清这个问题!
您可以在O(n + m)时间内完成此操作,其中n和m是列表的长度。这比通过第一个列表并检查每个元素是否包含在第二个列表中的幼稚方法要快得多。
我假设,从你的例子,你的参考数组不包含重复。如果它有处理这个问题的方法,但是它并不完全清楚你想要输出结果的样子。
建立一个位字段,这是一个数据结构,告诉你是否存在任何给定的元素,并且它用一个位表示每个可能的元素。因此,您可以使用一个int
来表示32个不同的输入/输出值。有一个Apache Commons实现可用,您可以直接使用。
解决问题的方法是通过参考数组,将它的每个元素放入位域。完成此操作后,您实际上有一个Set
,您可以通过查看是否在位域中设置其位,来测试任何给定值是否位于参考数组中。所以现在你通过你的候选数组,并且为每个元素测试它在位域中的存在。
即使可能值的范围很大,您仍然可以这样做。即使所有可能的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)。
都是总是排序顺序或增加/减少顺序? – luisluix 2014-10-16 22:46:39
哦,对不起,这个例子可能会让人困惑。序列从不排序。 – 2014-10-16 22:52:41
这实际上是差异所做的(只需用您的8位令牌替换行)http://en.wikipedia.org/wiki/Diff_utility有很多启发式方法来处理*性能良好的*案例。 – wildplasser 2014-10-16 23:03:32