Folosind un binar de căutare copac ca un corector ortografic

voturi
4

Vă întrebați modul cel mai EFICIENTĂ pentru a face un arbore binar de căutare într-un corector ortografic citind în 1000 să zicem cuvânt de dicționar fișier și având apoi să verificați un alt document care spune are câteva paragrafe.

Întrebat 05/12/2008 la 03:05
sursa de către utilizator
În alte limbi...                            


8 răspunsuri

voturi
8

un arbore ternar trie ar fi mai eficient

Publicat 05/12/2008 la 03:22
sursa de către utilizator

voturi
0

Dacă aveți nevoie pentru a face un auto sugerează căutare / prefix, de asemenea, apoi un copac copac sau Radix Patriciei este în valoare de uita la.

Publicat 05/12/2008 la 03:26
sursa de către utilizator

voturi
0

Cu exemplul ai dat, performanța este probabil să fie lipsită de relevanță, din moment ce pe un PC întreaga operațiune va dura aproximativ 1% din timpul necesar utilizatorului pentru a citi primul rezultat a vă arăta, cu condiția să nu utilizați un algoritm complet stupid . Dar totuși, voi presupune că problema este destul de mare că performanța este o problemă.

În cazul în care dicționarul fișierul este Pre-sortate (ca cele mai multe sunt), iar în cazul în care textul este relativ mic la dicționar așa cum ați descrie, atunci aș fi extrem de tentate pentru a sorta textul, probabil, eliminarea duplicatelor, și apoi iterează prin ambele liste side-by -side, folosind aceeași procedură ca un fel de îmbinare, cu excepția faptului că un raport dacă fiecare cuvânt de text este în dicționar în loc de o listă scoate îmbinată.

Acest lucru are loc de muncă în aproximativ M comparații log M pentru un fel, plus la cele mai multe comparații N + M pentru iterație, (eventual mai puțin, dar nu și complexitate mai puțin). Asta e destul de aproape de complexitate optimă pentru o operațiune de one-off: pentru a scăpa de termenul liniar în N trebuie să găsească modalități de a nu citi întregul dicționar de pe disc la toate. Sunt destul de sigur că e posibil să bsearch în dosar, mai ales având în vedere că cuvintele sunt destul de scurt, dar pentru mici N este știe nimeni dacă caută despre locul va fi de fapt mai rapid decât accesarea în serie a datelor.

Acesta are următoarele caracteristici:

  • Nu trebuie să țineți dicționarul în memorie, numai textul.
  • Cu toate acestea, a face doar o singură trecere peste dicționarul fișierul.
  • Tu nu faci nici o prelucrare costisitoare a dicționarului.

Desigur, în cazul în care fișierul dicționar nu este pre-sortate, atunci acest lucru nu funcționează, și dacă vă puteți păstra dicționarul agățat în jurul valorii în memorie pentru următoarea operație de Spellcheck atunci puteți amortizeze costul I / O și de prelucrare a acestuia în un copac în mai multe texte diferite, care va fi un câștig pe termen lung.

Dacă dicționarul este într-adevăr foarte mare, atunci s-ar putea beneficia de o stocați pe disc într-o formă de pre-prelucrată echivalent cu un arbore dezechilibrat ponderate în funcție de frecvențele relative ale diferitelor cuvinte în limba dumneavoastră. Apoi, puteți face mai puțin de O (N) de acces pe disc pentru texte mici, iar pe cele mai multe sisteme de operare nu deranjez încărcând-o în memorie, la toate, mmap doar fișierul și lăsați sistemul de operare vă faceți griji cu privire la aceasta. Pentru un dicționar mare, întregul clustere care conțin cuvinte care încep cu „dimetil“ nu trebuie să fie atins.

Un alt considerent este un arbore splay pentru dicționar. Un copac evazat se dezechilibrează ca te uiti lucrurile în ea, în scopul de a face valorile utilizate frecvent pentru a găsi mai repede. Cele mai multe texte utilizează un număr mic de cuvinte în mod repetat, astfel încât în ​​cazul în care textul este suficient de lung pentru a justifica acest lucru deasupra capului va câștiga în cele din urmă.

Ambele cele de mai sus sunt supuse punctul de Steven A Lowe că pentru siruri de caractere, un trie bate un copac normal. Nu știu dacă veți găsi un evazat Trie off-the-shelf, totuși.

Publicat 05/12/2008 la 03:55
sursa de către utilizator

voturi
1

Dacă sunteți doar încercarea de a vedea dacă există un anumit cuvânt din dicționar (adică, este scris corect), atunci nu cred că un arbore binar de căutare este ceea ce ești după. O modalitate mai bună de a stoca aceste informații ar fi într-un stil arbore în care fiecare nod succesive pe arborele este un caracter, și citind calea către nodul final vă oferă ortografia acelui cuvânt. De asemenea, ai nevoie să adăugați un marker pentru a indica un cuvânt sfârșit.

De exemplu: spune dicționarul are aceste cuvinte: masina, coș, pisica, cupa, tăiate

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

Verificarea dacă există un cuvânt este o chestiune de a privi fiecare literă în mod individual, și că există în fiii nodului curent.

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.

Cum stocați această informație este de până la tine. După cum a subliniat Steven, un ternare de căutare Trie ar putea fi calea de a merge: fiecare nod ar avea 27 de noduri posibile pentru copii.

Publicat 05/12/2008 la 04:16
sursa de către utilizator

voturi
3

Ești mort-setat pe folosind un arbore binar de căutare? Un filtru Bloom ar fi , probabil , o structură mai eficientă a datelor.

Publicat 05/12/2008 la 04:34
sursa de către utilizator

voturi
0

Văzând că aceasta este o întrebare temele am de gând să presupunem că trebuie să utilizați un copac simplu vechi binar (fără copaci rosu-negru, copaci AVL, copaci Radix, etc). Răspunsul atunci este de a încerca să păstreze copac echilibrat, așa cum se va construi din lista de cuvinte. O abordare este de a ȋntamplare lista înainte de a citi-o în, acest lucru dă rezultate rezonabile. Dar puteți obține rezultate mai bune, dacă pentru secvența de intrare (folosind aceeași comparație cu ceea ce folosește copac), apoi subdiviza recursiv de intrare se întoarce la punctul median până când nu rămân elemente. Rezultatul este un arbore echilibrat.

Am bătut până la trei moduri diferite de a face aceasta în 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);
}
Publicat 20/04/2011 la 21:27
sursa de către utilizator

voturi
1

Acest site - ul ar trebui să vă ajute are punerea în aplicare în Java.

Publicat 12/06/2011 la 04:07
sursa de către utilizator

voturi
0

După cum a sugerat un trie ar fi mai eficient decât un arbore binar, dar puteți utiliza un HashMap și hash fiecare cuvânt. Ai un dicționar mic (1000 de intrări). Pe măsură ce traversa documentul, verificați dacă cuvintele sunt în HashMap. Dacă nu sunt, cuvântul se presupune a fi scrise greșit.

Acest lucru nu vă va da posibilitatea de corecție a unui cuvânt scris greșit. Pur și simplu vă spune da sau nu (corect sau nu).

Dacă doriți sugestii de ortografie pentru cuvinte incorecte puteți începe de la cuvântul în fișierul, apoi genera toate cuvintele 1 edita distanță și se adaugă ca și copii ale cuvântului inițial. În acest fel vă construiți un grafic. Du-te 2 nivele de adâncime pentru viteza maximă față de precizie. Dacă generați un nod cuvânt care este în dicționar, îl puteți adăuga la o listă de posibile sugestii. La final, a reveni lista de posibile sugestii.

Pentru o mai bună verificare a ortografiei de asemenea, încercați să adăugați în potrivirea fonetic.

mare Yuh -> vezi Yah

Această metodă (de creare a graficelor de siruri de 1 edita distanță) este „lent“. Dar este un exercițiu academic bun. Compresia este O (n ^ ramuri).

Daca sunteti interesati aici este un link către una m - am construit (pentru distracție): https://github.com/eamocanu/spellcheck.graph

Unele grafice eșantion: https://github.com/eamocanu/spellcheck.graph/tree/master/graph%20photos

Am adăugat, de asemenea, o componentă UI la acesta, care generează graficele. Aceasta este o bibliotecă externă.

Publicat 15/12/2011 la 22:26
sursa de către utilizator

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