我有许多数组,其中包含500到1000个整数。我想在这些数组中找到某个序列模式的一部分的任何实例。例如,我有一个偏移模式
offset = [-15, -12, -5, -1, 1, 10, 20, 32]
和正整数的排序列表
A = [2, 8, 12, 15, 22, ...] # Length ~ 1000
我希望找到所有这样的整数N,以便对于a
中的每个offset
,N + a
是A
的元素。
但是,理想情况下,我可以为a
匹配所需的N
值设置一个阈值。因此,如果我的偏移量为3,可能只有N - 12
,N - 1
和N + 20
是A
中存在的值,我想保留N
。
我可以轻松编写一个暴力算法来测试这个条件 - 但是有成千上万的这样的数组要测试几个模式,我想知道是否有更好的方法可以解决这个问题。感谢。
根据要求,这里有一些蛮力算法的伪代码:
# Not perfect because it doesn't take into account possible boundary cutoffs
for a in A:
new_offset = [x + a for x in offset]
count = sum(x in A for x in new_offset)
if count >= threshhold:
# keep a, and work out N
答案 0 :(得分:1)
offsets = [-15, -12, -5, -1, 1, 10, 20, 32]
A = {2, 8, 12, 15, 22, ...} # a set of length ~ 1000
N = range(min(A)+min(offsets),max(A)+max(offsets)+1)
THRESHOLD = 3
NN = [num for num in N if sum((1 for offset in offsets if num+offset in A)) >= THRESHOLD]
或者,在您通过THRESHOLD
offsets = [-15, -12, -5, -1, 1, 10, 20, 32]
A = {2, 8, 12, 15, 22, ...} # a set of length ~ 1000
test_range = range(min(A)+min(offsets),max(A)+max(offsets)+1)
THRESHOLD = 3
N = set()
for value in test_range:
count = 0
for offset in offsets:
if value+offset in A: count += 1
else: continue
if count == 3:
N.add(value)
break
答案 1 :(得分:1)
如果我正确理解了这个问题。在我看来,如果len(偏移)<< len(A),对于offset中的每个值,您可以计算A-offset,然后计算每个值出现的行数。如果该值至少出现x次,其中x是您的最小截止值,那么该值符合您的critereon 。
例如,如果您的值是: 偏移= [ - 3,-1,1] A = [1,3,5,7]
你会计算 [4,6,8,10] [2,4,6,8] [0,2,4,6]
然后你算了: 0:1 2:2 4:3 6:3 8:2 10:1
所以4和6应该适用于N.
这种复杂性将是O(len(偏移)* len(A))
答案 2 :(得分:0)
我认为这是与上述类似的算法,但不确定。
from collections import Counter
counters = Counter()
# Python 2.6:
# from collections import defaultdict
# counters = defaultdict(int)
from itertools import product
Aset = set(A)
for aval, offset in product(A, offset):
counters[aval-offset] += 1
# 3 is the threshold here; change at will.
[key for key, val in counters.items() if val > 3]
似乎有效。我们在做什么:如果有一个数字N使得N +偏移在A中,那么我们可以在A中转到该值,并且Aval-offset = N.小,愚蠢的例子:
A = [1,3,5,10]
offset = [-2, 5]
有一个数字,5,符合此标准。但是,我们还不知道。这个数字是3 + 2和10-5。我们将第一次进入-2,然后通过向每个A添加2来获得[3,5,7,12]。然后,我们将再次通过5,得到[-4,-2] ,0,5]从每个A减去5.这给我们这样的计数器:
-4: 1
-2: 1
0: 1
3: 1
5: 2
7: 1
12: 1
5是唯一一个匹配两个条目的人。
在给定的偏移量和0到4000之间随机生成的约1000个随机整数序列(实际最小/最大6/3999,生成1200个数字,通过列表(set())删除重复项,然后排序),创建字典花了~2.5 mS。如果重要的话,对于这个算法,你真的不需要对A进行排序,但是删除重复项是必要的(除非你真的希望它计算两次)。