Korzystanie z funkcji generatora ułatwia zadanie.
table = [(2,3),(5,6),(12,20),(21,25),(28,28),(35,48),(53,55)]
def gaps_between(intervals):
prec = intervals[0][1] + 1
for L,H in intervals:
print '\nprec = %d (L,H) = (%d,%d)' % (prec,L,H)
print 'prec = %d <= L-1 = %d : %s' % (prec,L-1,prec<=L)
if prec<=L-1:
yield (prec,L-1)
prec = H + 1
print 'next prec = %d' % prec
holes = list(gaps_between(table))
print
print 'table =',table
print 'holes =',holes
W poprzedniej odpowiedzi użyłem iteratora zdefiniowanego wewnątrz generatora.
Aby tego uniknąć, tutaj powyżej używam strategii:
definiowanie first prec = first H = intervals[0][1]
.
Biorąc pod uwagę fakt, że H>=L
dla każdej pary (L, H), prowadzi to do
first H > first L - 1
->first prec > first L - 1
.
Dlatego pierwsze badanie dotyczące pierwszego przedziału jest zawsze fałszywe, a rzeczywisty proces rozpoczyna się w drugim przedziale.
prec = 3 (L,H) = (2,3)
prec = 3 <= L-1 = 1 : False
next prec = 4
prec = 4 (L,H) = (5,6)
prec = 4 <= L-1 = 4 : True
next prec = 7
prec = 7 (L,H) = (12,20)
prec = 7 <= L-1 = 11 : True
next prec = 21
prec = 21 (L,H) = (21,25)
prec = 21 <= L-1 = 20 : True
next prec = 26
prec = 26 (L,H) = (28,28)
prec = 26 <= L-1 = 27 : True
next prec = 29
prec = 29 (L,H) = (35,48)
prec = 29 <= L-1 = 34 : True
next prec = 49
prec = 49 (L,H) = (53,55)
prec = 49 <= L-1 = 52 : True
next prec = 56
table = [(2, 3), (5, 6), (12, 20), (21, 25), (28, 28), (35, 48), (53, 55)]
holes = [(4, 4), (7, 11), (26, 27), (29, 34), (49, 52)]
Wynikiem jest poprawne:
- daje szczeliny (4,4) w zakresie (2-3) i (5-6)
- nie ma różnicy między (12,20) i (21,25)
- wartość 28 obecna w (28, 28) nie występuje w żadnej szczelinie
OP mówi, że odstępy nie są zachodzące na siebie i są sortowane.
Jednakże test if prec<=L-1
jest obowiązkowa, inaczej sąsiednie przedziały daje błąd:
bez tego testu, wynik będzie zawierać
....., (7, 11), (21, 20), (26, 27), .......
.
Zdarza się, że z tego obowiązkowego testu następujące wykazy odstępach
[[ 8, 9],[14, 18],[18, 32]]
[[8, 9], [14, 18], [19, 20], [16, 21], [23, 32]]
że są nadmiernie docierania (nie to, co mówi OP)
i że dałoby błąd bez testu
don W rzeczywistości nie powoduje żadnych błędów.
Reguła dla listy interwałów, aby podać poprawną listę luk za pomocą powyższego kodu, polega na tym, że przedziały muszą być posortowane wzdłuż drugiego elementu.
.
Zastąpienie yield (prec,L-1)
z yield range(prec,L)
spowoduje, że przerwy będą stanowiły zakresy.
Zastępując na przykład yield (prec,L-1)
z holes.append((prec,L-1))
, można zapisać kod bez funkcji.
Po wielu wielu wnioskach, które pomogły mi @gnibbler, oraz licznych zmianach w moim kodzie, zakończyłem ostatecznie. Zobacz proszę i powiedz mi, co o tym sądzisz. – eyquem
@eyquem Aby poprawić twoją odpowiedź, edytowałbym komentarz, w jaki sposób dotarłeś do odpowiedzi, aby odpowiedź była krótka i słodka. – WilliamKF