与えられた配列:
array = [16 16 16 22 23 23 23 25 52 52 52]
3 つの繰り返し数の要素を指すインデックスのリストを返したい。この場合、次のようになります。
indices = find_sequence(nbr_repeats = 3)
print indices
[0 1 2 4 5 6 8 9 10]
実装するために使用する最速かつ最も洗練されたアルゴリズムは何find_sequence
ですか?
与えられた配列:
array = [16 16 16 22 23 23 23 25 52 52 52]
3 つの繰り返し数の要素を指すインデックスのリストを返したい。この場合、次のようになります。
indices = find_sequence(nbr_repeats = 3)
print indices
[0 1 2 4 5 6 8 9 10]
実装するために使用する最速かつ最も洗練されたアルゴリズムは何find_sequence
ですか?
私が知っている最も簡単な方法は...最初に数字を見た場所を追跡することです. 別の数字が見つかるまで続けます。シーケンスが十分に長い場合は、シーケンスの最初から最後の直前まですべての数字を追加します。
(もちろん、要素のチェックが終わったら、シーケンスの長さもチェックする必要があります。私は、最後の繰り返しで要素チェックをスキップすることでそれを行いました。)
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
これは、ボイヤームーア文字列検索アルゴリズムの特殊なケースのように見えます。使用する言語には文字列検索の最適化が含まれるため、おそらく最もエレガントな答えは、データを文字配列(つまり文字列)として扱い、言語に組み込まれている文字列検索機能を使用してください...これは、数値が言語でサポートされている文字セットに適合する場合にのみ機能することに注意してください(たとえば、ASCIIで128より大きい数値は使用しないでください)。
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
言語を指定しなかったため、ここに疑似コードを示します。
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
編集:元のインデックスを台無しにするため、並べ替えに関するコメントを削除しました。
注:最後の同じ要素のリストを維持する代わりに、最後の要素とその表示回数を保持することもできます