2008-11-13 13 views
10

Powiedzmy, że przechodzimy przez wykres i chcemy szybko stwierdzić, czy dany węzeł był widziany wcześniej czy nie. Mamy kilka ustalonych warunków wstępnych.Szybkie wyszukiwanie elementów dla języka funkcyjnego (Haskell)

  1. węzły oznaczone liczbami wartości 1..n
  2. wykres jest realizowane z węzłami o listę przylegania
  3. Każda wartość całkowitą od 1..n występuje na wykresie, który ma wielkość N

Jakieś pomysły na zrobienie tego w czysto funkcjonalny sposób? (Nie dozwolone tabele lub tablice skrótu).

Chcę struktury danych z dwiema funkcjami nad nią pracującymi; add (dodaje napotkaną liczbę całkowitą) i lookup (sprawdza czy liczba całkowita została dodana). Oba powinny korzystnie przyjąć czas (n) zamortyzowany na N powtórzeń.

Czy to możliwe?

Odpowiedz

8

Można użyć numeru Data.Set. Dodajesz element, tworząc nowy zestaw ze starego z insert i przekazujesz nowy zestaw dookoła. Sprawdzasz, czy element jest elementem zestawu z member. Obie operacje to O (log n).

Być może warto rozważyć użycie monady stanu do gwintowania przejścia zestawu.

+0

Zakładam, że Data.Set da logarytmiczną lub quasi-stałą wydajność na addToSet i member, w przeciwieństwie do oczekiwanej wydajności w czasie stałym z tabelami hash? –

+0

Chris, masz rację. Dane.Wstawianie i wyszukiwanie operacji to O (log n). – namin

+3

Jeśli twoje liczby całkowite są wystarczająco małe dla typu Int, możesz użyć Data.IntSet, czyli zoptymalizowanej wersji Set. – mattiast

1

Efektywne wyszukiwanie elementów w językach funkcyjnych jest dość trudne. Data.Set (jak pokazano powyżej) zaimplementowano przy użyciu drzewa binarnego, które można zbudować w czysto funkcjonalny sposób, zapewniając operacje wyszukiwania w O (log n). HashTables (które nie są czysto funkcjonalne) miałyby O (1).

0

Wierzę, że Data.BitSet może być O (n).

Powiązane problemy