私は、一連の数字の中で与えられた長さの不連続点(ギャップ)を見つける問題に直面しています。したがって、たとえば、[1,2,3,7,8,9,10]
と隙間がlength=3
の場合、[4,5,6]
と表示されます。ギャップがlength=4
なら、何も見つかりません。実際のシーケンスはもちろん、はるかに長いです。私はかなりの記事でこの問題を見てきましたが、さまざまなアプリケーションと可能な実装がありました。ビットマスキングでデータギャップを見つける
私は考えていたかもしれませんが、比較的速くなければならないのは、利用可能な数字の1と欠損の0を含むビット配列として完全な集合を表現することです。したがって、上記は[1,1,1,0,0,0,1,1,1,1]
のようになります。次に、すべての位置が1になるまで、指定された長さの配列を完全なセットでXORマスクするウィンドウ関数を実行することができます。これは、およそ〜O(n)のシーケンス全体にわたる単一パスと、各走行でマスキングする。
は、ここで私が思い付くことをどうにか何:
def find_gap(array, start=0, length=10):
"""
array: assumed to be of length MAX_NUMBER and contain 0 or 1
if the value is actually present
start: indicates what value to start looking from
length: what the length the gap should be
"""
# create the bitmask to check against
mask = ''.join([1] * length)
# convert the input 0/1 mapping to bit string
# e.g - [1,0,1,0] -> '1010'
bits =''.join([ str(val) for val in array ])
for i in xrange(start, len(bits) - length):
# find where the next gap begins
if bits[i] != '0': continue
# gap was found, extract segment of size 'length', compare w/ mask
if (i + length < len(bits)):
segment = bits[i:i+length]
# use XOR between binary masks
result = bin(int(mask, 2)^int(segment, 2))
# if mask == result in base 2, gap found
if result == ("0b%s" % mask): return i
# if we got here, no gap exists
return -1
これは〜100K(< 1秒)のためにかなり速いです。私はこれをより速くする方法と大きなセットでより効率的にする方法についてのヒントを感謝します。ありがとう!
startは配列idxであり、値ではありませんか? – kevpie
私は問題の権利を理解していないのです。 'a [i + 1] - a [i] == gap + 1'の隣接要素を探すことはできませんか? –
@Marcelo私はあなたが本当にできると思うし、OPは真剣に、最適化について理解していないアイデアに基づいて、事を過度に複雑にしていると思う。私はこの仮定について私の答えを書いた。 –