Я столкнулся с проблемой поиска разрывов (разрывов) заданной длины в последовательности чисел. Так, например, учитывая [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]
. Затем, возможно, запустите оконную функцию, которая будет маскировать XOR массив заданной длины с полным набором до тех пор, пока все местоположения не приведут к 1. Это потребует одного прохода по всей последовательности примерно за ~ 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
Это довольно быстро, ~ 100к (‹1 сек). Буду признателен за советы, как сделать это быстрее / эффективнее для больших сетов. Благодарность!
a[i + 1] - a[i] == gap + 1
? - person Marcelo Cantos   schedule 07.12.2010find_gap([1,1,1,0,0,0,1,1,1,1], 0, 3)
вернет4
. Кроме того, я указалstart
, а не idx, чтобы разрешить поиск с произвольного числа. Извините, если я не понял. - person sa125   schedule 07.12.2010