2014-11-24 28 views
8

że mam następującą listę numerów:Krotki zamkniętych ciągłych odstępach

my_array = [0, 3, 4, 7, 8, 9, 10, 20, 21, 22, 70] 

chciałbym znaleźć każdy zamknięty przedział zawierający kolejnych liczb całkowitych bez przerw w tej liście. Jeśli dla dowolnej liczby na liście istnieje wiele takich interwałów, my zachowujemy tylko największy takich interwałów. Prawidłowa odpowiedź powyżej powinny być:

[0, 0] 
[3, 4] 
[7, 10] 
[20, 22] 
[70, 70] 

Aby to zobaczyć, trzeba pamiętać, na przykład:

  • Zamknięty przedział [0,0] zawiera całkowitą 0 nie zawiera braków, a żaden z jego członków są zawarte w każdy inny zamknięty interwał.

  • Zamknięty przedział [3,4] nie zawiera przerw, a jego elementy nie są zawarte w żadnym innym zamkniętym interwale bez przerw, które są większe od siebie.

Jak mogę to zrobić w numpy? Zacząłem pisać algorytm, który używa np.diff(my_array) do wykrywania przejść w tablicy, ale zawodzi w przypadku narożnych przypadków, takich jak interwały zawierające tylko jeden element.

+0

jak zdefiniować, każda zamknięta ciągła przerwa ??, co jest regułą ?? – Hackaholic

+0

@Hackaholic I znacznie rozszerzyłem OP, aby wyjaśnić, co mam na myśli. daj mi znać, jeśli nadal jest niejasna. –

+0

Mam to teraz, teraz jasne, – Hackaholic

Odpowiedz

3

Nie mam instalacji numpy pod ręką, ale to jest podejście, które brałbym. Najpierw osobno zajmij się przypadkiem pustej tablicy. Sortuj tablicę, jeśli nie jest jeszcze posortowana i użyj np.diff do obliczenia różnic.

0, 3, 4, 7, 8, 9, 10, 20, 21, 22, 70 
    3 1 3 1 1 1 10 1 1 48 

Sprawdź różnice za bycie > 1.

1 0 1 0 0 0 1 0 0 1 

Aby uzyskać początki przerwach, umieścić 1 na początku i wybierz odpowiednie elementy tablicy. Aby uzyskać końcówki, umieść na końcu 1 i wybierz odpowiednie elementy tablicy.

0, 3, 4, 7, 8, 9, 10, 20, 21, 22, 70 
1 1 0 1 0 0 0 1 0 0 1 
0 3  7    20   70 

0, 3, 4, 7, 8, 9, 10, 20, 21, 22, 70 
1 0 1 0 0 0 1 0 0 1 1 
0  4   10   22 70 

Wykonanie (w dużej mierze przez user815423426):

def get_intervals(my_array): 
    my_diff = np.diff(my_array)>1 
    begins = np.insert(my_diff, 0, 1) 
    ends = np.insert(my_diff, -1, 1) 
    return np.array(np.dstack((my_array[begins], my_array[ends]))) 

my_array = np.array([0, 3, 4, 7, 8, 9, 10, 20, 21, 22, 70]) 
> get_intervals(my_array) 
array([[ 0, 0], 
     [ 3, 4], 
     [ 7, 10], 
     [20, 22], 
     [70, 70]]) 
2

Czysta implementacja Pythona:

def findContinuousIntervals(numbers): 
    if not numbers: 
     return [] 

    sortedNumbers = sorted(numbers) 

    result = [(sortedNumbers[0], sortedNumbers[0])] 
    for n in sortedNumbers: 
     a, b = result[-1] 
     if abs(b - n) <= 1: 
      result[-1] = (a, n) 
     else: 
      result.append((n, n)) 
    return result