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

Python 在整数数组中查找偏移序列,python,arrays,algorithm,Python,Arrays,Algorithm,我有许多500到1000个整数的数组。我想在这些数组中找到特定序列模式的一部分的任何实例。例如,我有一个偏移模式 offset = [-15, -12, -5, -1, 1, 10, 20, 32] 和正整数的排序列表 A = [2, 8, 12, 15, 22, ...] # Length ~ 1000 我想找到所有这样的整数N,对于offset中的每个a,N+a是a的一个元素 然而,理想情况下,我能够为使N匹配所需的a值的数量设置阈值。因此,如果我的偏移量是3,可能只有N-12、N-1和

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

offset = [-15, -12, -5, -1, 1, 10, 20, 32]
和正整数的排序列表

A = [2, 8, 12, 15, 22, ...] # Length ~ 1000
我想找到所有这样的整数N,对于
offset
中的每个
a
N+a
a
的一个元素

然而,理想情况下,我能够为使
N
匹配所需的
a
值的数量设置阈值。因此,如果我的偏移量是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
或者,在通过
阈值后短路

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

如果我理解正确的话。在我看来,如果len(offset)我认为这是一个与上面类似的算法,但不确定

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进行第一次计算,通过将2加回到每个A得到[3,5,7,12]。然后,我们将再次对5进行计算,通过从每个A减去5得到[-4,-2,0,5]。这给了我们如下计数器:

-4: 1
-2: 1
 0: 1
 3: 1
 5: 2
 7: 1
12: 1
5是唯一匹配两个条目的


对于给定的偏移量和随机生成的约1000个介于0和4000之间的随机整数序列(实际最小值/最大值6/3999,生成1200个数字,通过列表(set())删除重复项,然后进行排序),创建字典需要约2.5 mS。如果有关系,对于此算法,您实际上不需要对,但是删除重复项是必要的(除非您真的希望它计数两次)

如果你至少告诉我们暴力算法是什么,这可能有助于明确你想要什么。完全可以使用列表理解来做到这一点。@wnnmaw:对于
offset
中的
a
中的至少一些
a
N+a
a
中。我需要一个需要匹配的偏移值数量的可变阈值@莱斯特,我会写一些pseudocode@user2852809,是的,我注意到当我重新阅读你的帖子时,偏移量的典型长度是多少,你希望看到什么范围的整数(例如,数组中的所有整数都小于10000)?(对于长偏移和小范围,使用快速傅里叶变换可能会更好),但是如果max(A)是一个非常大的数字呢?如果我没弄错的话,这将是非常低效的。制作一个集合而不是一个列表可能更有效?@peterdererivaz谢谢,好主意!对于这些优化,我通常的心理检查表是:“他把它作为一个集合给我了吗?没有。他是否明确表示它们是唯一的值?没有。”但是,因为我们不关心顺序或a,也不关心重复的值是否得到测试(不管怎样,结果是否不同),所以这并不重要!所以我只是用1000个介于0和9999之间的随机数来测试这个问题,并没有花太长的时间,最多可能是半秒钟。不过有一点需要注意,您需要在第三行中使用大写字母A。您应该修复
A[0]
A[-1]
,同时,集合不可能建立索引。:)
-4: 1
-2: 1
 0: 1
 3: 1
 5: 2
 7: 1
12: 1