在整数数组中查找偏移序列

时间:2014-01-23 22:20:04

标签: python arrays algorithm

我有许多数组,其中包含500到1000个整数。我想在这些数组中找到某个序列模式的一部分的任何实例。例如,我有一个偏移模式

offset = [-15, -12, -5, -1, 1, 10, 20, 32]

和正整数的排序列表

A = [2, 8, 12, 15, 22, ...] # Length ~ 1000

我希望找到所有这样的整数N,以便对于a中的每个offsetN + aA的元素。

但是,理想情况下,我可以为a匹配所需的N值设置一个阈值。因此,如果我的偏移量为3,可能只有N - 12N - 1N + 20A中存在的值,我想保留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

3 个答案:

答案 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进行排序,但是删除重复项是必要的(除非你真的希望它计算两次)。