给出一个数组:
array = [16 16 16 22 23 23 23 25 52 52 52]
我想返回一个指向三个重复数字元素的索引列表。 在这种情况下,将是:
indices = find_sequence(nbr_repeats = 3)
print indices
[0 1 2 4 5 6 8 9 10]
用于实现find_sequence
的最快和最优雅的算法是什么?
答案 0 :(得分:2)
我知道的最简单的方式......记下你看到一个数字的第一个地方。继续前进直到找到不同的数字,然后如果序列足够长,则从序列的开头直到结束之前添加所有数字。
(当然,在你完成元素检查之后,你还必须检查序列长度。我是通过迭代一遍结束而只是跳过最后一次迭代的元素检查来完成的。)
To find_repeats (input : list, minimum : integer):
start := 0
result := []
for each x from 0 to (input length):
' "*or*" here is a short-circuit or
' so we don't go checking an element that doesn't exist
if x == (input length) *or* array[x] != array[start]:
if (x - start) >= minimum:
append [start...(x - 1)] to result
start := x
return result
答案 1 :(得分:1)
基于OP的假设:
nbr_repeats
这可能有效:
def find_sequence(nbr_repeats, l):
res = []
current = -1
count = 0
idx = 0
for i in l:
if i == current:
count += 1
if count == nbr_repeats:
for k in reversed(range(nbr_repeats)):
res.append(idx-k)
else:
current = i
count = 1
idx += 1
return res
答案 2 :(得分:1)
这在我看来就像Boyer-Moore string search algorithm的一个特例,并且由于您使用的任何语言都包含字符串搜索的优化,也许最优雅的答案是将您的数据视为字符数组(即字符串) )并使用您的语言内置的字符串搜索功能...请注意,这只适用于您的数字符合您的语言支持的字符集(例如,ASCII中没有大于128的数字)
答案 3 :(得分:0)
由于您未指定语言,因此这是伪代码:
find_sequence(array: array of int, nbr_repeats: int) : array of int
retVal = emty array of int // the return'd array
last = empty array of int // collection of last seen same elements
i = -1
for each element e in array
++i
if (isempty(last))
add(last, e) // just starting
else if (count(last, e) >= nbr_repeats)
add(retVal, i-nbr_repeats) // found an index
else if (e == first(last))
add(last, e) // we have encountered this element before
else
if (count(last, e) >= nbr_repeats)
for (j=nbr_repeats-1; j>0; --j)
add(retVal, i-j) // catching up to i with indices
last = [e] // new element
if (count(last, e) >= nbr_repeats)
for (j=nbr_repeats-1; j>0; --j)
add(retVal, i-j) // handle end of array properly
return retVal
编辑:删除了关于排序的评论,因为它会破坏原始索引。
注意:您也可以保留最后一个元素及其看到计数,而不是维护最后一个相同元素的列表