Korzystanie z binarne drzewo poszukiwań jako sprawdzania pisowni

głosy
4

Zastanawiasz się najbardziej efficent sposób dokonać wyszukiwania binarne drzewo do sprawdzania pisowni, czytając w powiedzmy 1000 word pliku słownika, a następnie o to sprawdzić inny dokument, który ma powiedzieć kilka akapitów.

Utwórz 05/12/2008 o 03:05
źródło użytkownik
W innych językach...                            


8 odpowiedzi

głosy
8

trójskładnikowy drzewa trie byłby bardziej efektywny

Odpowiedział 05/12/2008 o 03:22
źródło użytkownik

głosy
0

Jeśli trzeba zrobić auto sugerują wyszukiwanie / prefiks, jak również, a następnie drzewo Patricia lub radix drzewa warto przyjrzeć.

Odpowiedział 05/12/2008 o 03:26
źródło użytkownik

głosy
0

Z przykład dałeś, wydajność może być bez znaczenia, ponieważ na komputerze cała operacja zajmie około 1% czas potrzebny użytkownikowi czytać pierwszy wynik Ci pokazać, pod warunkiem, że nie korzystają z całkowicie głupi algorytm , Ale nadal będę zakładać, że problem jest na tyle duże, że wydajność jest problem.

Jeśli plik słownika presorted (jak większość z nich), a jeśli tekst jest niewielka w stosunku do słownika jak opisujesz, to byłoby bardzo skłonny do sortowania tekstu, być może usuwanie duplikatów, a następnie iterację obu listach side-by -side stosując tę ​​samą procedurę jak w seryjnej rodzaju, z wyjątkiem zgłosić każde słowo czy tekst ma w słowniku zamiast wyprowadzania listę połączone.

To nie praca w dzienniku o M M porównań do rodzaju, a także w większości porównań N + M dla iteracji (być może mniej, ale nie złożoność mniej). To dość blisko optymalnej złożoności dla operacji jednorazowej: pozbyć terminu liniowego w N trzeba znaleźć sposoby, aby nie przeczytać cały słownik z dysku w ogóle. Jestem prawie pewien, że to możliwe bsearch do pliku, zwłaszcza biorąc pod uwagę, że słowa są dość krótkie, ale dla małych N to tylko zgadywać, czy szukając o miejscu rzeczywiście będzie szybciej niż seryjnie dostępu do danych.

Posiada następujące cechy:

  • Nie musisz trzymać słownika w pamięci tylko tekst.
  • Niemniej jednak, trzeba tylko zrobić jeden podaniem w pliku słownika.
  • Nie rób żadnych drogich przetwarzanie słownika.

Oczywiście jeśli plik słownika nie wstępnie posortowane wtedy to nie działa, i czy można zachować słownika kręcących się w pamięci do następnej operacji sprawdzania pisowni następnie można amortyzować koszt I / O i przetwarzania go na drzewo na kilku różnych tekstów, które będzie wygrać na dłuższą metę.

Jeśli słownik jest naprawdę ogromny, to możesz skorzystać z zapisywania go na dysku w ampułko-przetworzonej formie odpowiadającej niezrównoważonej drzewa ważone według względnej częstości poszczególnych słów w swoim języku. Następnie można zrobić mniej niż O (n) dostęp do dysku dla małych tekstów, a na większości systemów operacyjnych nie przeszkadza załadowanie go do pamięci w ogóle, po prostu mmap pliku i niech OS martwić. Dla dużego słownika całe klastry zawierające słowa zaczynające się od „dimetylo” nie musi być dotykana.

Innym zjawiskiem jest drzewo splay do słownika. Drzewo splay niewyważenia się, jak szukać rzeczy w nim, w celu uczynienia często używane wartości szybciej znaleźć. Większość tekstu wykorzystuje niewielką liczbę słów wielokrotnie, więc jeśli tekst jest wystarczająco długi, aby uzasadnić obciążenie to będzie ostatecznie wygrać.

Oba powyższe podlegają punktu A Steven Lowe, że dla ciągów, o trie bije normalne drzewo. Nie wiem, czy znajdziesz się off-the-shelf pochylenie Trie, choć.

Odpowiedział 05/12/2008 o 03:55
źródło użytkownik

głosy
1

Jeśli jesteś po prostu staramy się zobaczyć, czy dany wyraz występuje w słownika (to znaczy, że jest napisane poprawnie), to nie sądzę, wyszukiwanie binarne drzewo jest co jesteś po. Lepszym sposobem przechowywania tych informacji byłoby w stylu drzewa, gdzie każdy kolejny węzeł w drzewie jest jeden znak, a czyta ścieżkę do węzła końcowego daje pisownię tego słowa. Można by też trzeba dodać znacznik, aby wskazać słowo kończy.

Np powiedzieć słownika ma te słowa: samochód, wózek, kota, puchar, cięcie

- C
  - A
    - R
      - end
      - T
    - T
      - end
  - U
    - P
      - end
    - T
      - end

Sprawdzenie, czy istnieje słowo to kwestia patrzenia na każdą literę z osobna, i że istnieje ona w dzieci bieżącego węzła.

Check for "cat"
Does "C" exist at the root level? Yes, move to the next letter.
Does "A" exist underneath C? Yes, move on.
Does "T" exist underneath A? Yes, move on.
Is there a word ending after the T? Yes. Word exists.

Check for "cu"
Does "C" exist at the root level? Yes, move to the next letter.
Does "U" exist at the root level? Yes, move to the next letter.
Is there a word ending after the U? No. Word does not exist.

Jak przechowywać te informacje do Ciebie. Jak Steven wskazał, A Ternary Szukaj Trie może być droga: każdy węzeł będzie miał 27 możliwych węzłów potomnych.

Odpowiedział 05/12/2008 o 04:16
źródło użytkownik

głosy
3

Jesteś martwy ustawiony na użyciu wyszukiwarki binarne drzewo? Filtr Bloom będzie prawdopodobnie bardziej efektywne struktury danych.

Odpowiedział 05/12/2008 o 04:34
źródło użytkownik

głosy
0

Widząc, że jest to pytanie zadanie domowe mam zamiar założyć, że trzeba użyć zwykły stary binarne drzewo (nie czerwono-czarny drzewa, drzewa AVL, Radix drzew, etc.). Odpowiedź jest więc, aby utrzymać drzewo wyważone, jak budować go z listy słów. Jednym ze sposobów jest losowo z listy przed odczytaniem go, to daje dobre efekty. Ale można uzyskać lepsze rezultaty, jeśli zamówienie sekwencję wejściową (używając tego samego porównania jak to, co wykorzystuje drzewo), a następnie rekursywnie podzielić wejście zwrotu środkowy aż żadne elementy pozostają. Rezultatem jest zrównoważony drzewo.

Zapukałem trzy różne sposoby robi to w języku C #:

private static IEnumerable<T> BinaryTreeOrder<T>(IList<T> range, int first, int last)
{
  if (first > last)
  {
    yield break;
  }

  int mid = (first + last) / 2;
  yield return range[mid];
  foreach (var item in BinaryTreeOrder(range, first, mid - 1))
  {
    yield return item;
  }
  foreach (var item in BinaryTreeOrder(range, mid + 1, last))
  {
    yield return item;
  }    
}

private static void BinaryTreeOrder<T>(IList<T> range, int first, int last, 
                                       ref IList<T> outList)
{
  if (first > last)
  {
    return;
  }

  int mid = (first + last) / 2;
  outList.Add(range[mid]);
  BinaryTreeOrder(range, first, mid - 1, ref outList);
  BinaryTreeOrder(range, mid + 1, last, ref outList);
}

private static void BinaryTreeOrder<T>(IList<T> range, int first, int last, 
                                       ref BinaryTree<T> tree) where T : IComparable<T>
{
  if (first > last)
  {
    return;
  }

  int mid = (first + last) / 2;
  tree.Add(range[mid]);
  BinaryTreeOrder(range, first, mid - 1, ref tree);
  BinaryTreeOrder(range, mid + 1, last, ref tree);
}
Odpowiedział 20/04/2011 o 21:27
źródło użytkownik

głosy
1

Ta strona powinna pomóc ma wdrożenia w Javie.

Odpowiedział 12/06/2011 o 04:07
źródło użytkownik

głosy
0

Jak zaproponował trie będzie bardziej wydajny niż binarnego drzewa, ale można użyć HashMap i hash każde słowo. Masz mały słowniku (1000 wpisów). Jak można przemierzać dokument należy sprawdzić, czy słowa są w hashmap. Jeśli nie są, słowo Zakłada się błędnie.

To nie daje możliwej korekty do błędnie napisanego słowa. To po prostu mówi, tak lub nie (poprawne, czy nie).

Jeśli chcesz propozycji pisowni niewłaściwych słów można zacząć od słowa w pliku, a następnie wygenerować wszystkie słowa 1 edycja odległości i dodawać je jako dzieci wstępnym słowie. W ten sposób budujesz wykres. Idź 2 poziomy głębokości dla maksymalnej prędkości vs dokładności. Jeśli wygenerować węzeł słowo, które jest w słowniku, możesz dodać go do listy możliwych sugestii. Na koniec, należy zwrócić listę możliwych sugestii.

Dla lepszego sprawdzania pisowni, także spróbować dodać fonetycznej dopasowywania.

morze yuh -> patrz JAH

Ta metoda (tworzenia wykresów ciągów 1 edycja away) jest „wolna”. Ale jest to dobre ćwiczenie akademickie. Czas trwania wynosi O (N ^ gałęzie).

W razie zainteresowania tutaj jest link do jednego Zbudowałem sobie (dla zabawy): https://github.com/eamocanu/spellcheck.graph

Niektóre przykładowe wykresy: https://github.com/eamocanu/spellcheck.graph/tree/master/graph%20photos

Dodałem też składnik UI do niego, który generuje wykresy. To zewnętrznej biblioteki.

Odpowiedział 15/12/2011 o 22:26
źródło użytkownik

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more