Ved hjelp av en binært søketre som en stavekontroll

stemmer
4

Lurer på den mest effektiv måte å gjøre et binært søketre inn en stavekontroll ved å lese i si 1000 ord ordboken fil og deretter å ha det sjekke et annet dokument som sier har et par avsnitt.

Publisert på 05/12/2008 klokken 02:05
kilden bruker
På andre språk...                            


8 svar

stemmer
8

en trefoldig tre trie ville være mer effektiv

Svarte 05/12/2008 kl. 02:22
kilden bruker

stemmer
0

Hvis du trenger å gjøre en automatisk foreslå / prefiks søk også, så en patricia tre eller Radix treet er verdt å se på.

Svarte 05/12/2008 kl. 02:26
kilden bruker

stemmer
0

Med eksempelet du ga, er ytelsen sannsynlig å være irrelevant, siden på en PC hele operasjonen tar ca 1% av tiden det tar brukeren til å lese det første resultatet du viser, forutsatt at du ikke bruker en helt dum algoritme . Men likevel, vil jeg anta at problemet er stort nok til at ytelsen er et problem.

Hvis ordboken filen er presorted (som de fleste er), og hvis teksten er liten i forhold til ordlisten som du beskriver, så jeg ville bli sterkt fristet til å sortere teksten, kanskje fjerne duplikater, og deretter iterere gjennom begge listene side-by -siden ved hjelp av samme prosedyre som en flettesortering, bortsett fra at du rapporterer om hver tekst ord er i ordboken i stedet for å sende ut en sammenslått liste.

Dette gjør jobben i ca M log M sammenligninger for den typen, pluss at de fleste N + M sammenligninger for gjentakelse, (muligens mindre, men ikke kompleksiteten-mindre). Det er ganske nær optimal kompleksitet for en engangsoperasjon: å bli kvitt den lineære uttrykket i N du trenger for å finne måter å ikke lese hele ordboken fra disk i det hele tatt. Jeg er ganske sikker på at det er mulig å bsearch inn i filen, særlig gitt at ordene er ganske kort, men for liten N det er ingen som kan gjette enten søker om stedet vil faktisk være raskere enn serielt tilgang til data.

Den har følgende egenskaper:

  • Du trenger ikke å holde ordbok i minnet, bare teksten.
  • Likevel, du bare gjøre en pasning over ordboken filen.
  • Du trenger ikke gjøre noen dyre behandling av ordboken.

Selvfølgelig hvis ordboken filen er ikke pre-sortert da dette ikke fungerer, og hvis du kan holde ordboken hengende rundt i minne for neste stavekontroll operasjonen så kan du amortisere kostnadene for I / O og for å behandle den i et tre over flere ulike tekster, som vil være en seier i det lange løp.

Hvis ordlisten er virkelig stor, så du kan ha nytte av å lagre den på disken i en pre-bearbeidet form tilsvarer en ubalansert tre vektet i henhold til de relative frekvensene av de ulike ordene i språket ditt. Deretter kan du gjøre mindre enn O (N) disktilgang for små tekster, og på de fleste operativsystemer ikke bry legger det inn i minnet i det hele tatt, bare mmap filen og la OS bekymre deg for det. For en stor ordbok, hele klaser som inneholder ord som begynner med "dimetyl" behøver aldri bli rørt.

En annen vurdering er en spriker tre for ordlisten. En spriker tre ubalanser seg som du ser ting opp i det, for å gjøre ofte brukte verdier raskere å finne. De fleste tekst bruker et lite antall ord gjentatte ganger, så hvis teksten er lang nok til å rettferdiggjøre overhead dette vil vinne til slutt.

Begge de ovennevnte er underlagt Steven A Lowe poeng at for strykere, slår en trie en normal treet. Vet ikke om du finner en off-the-sokkel spriker trie, skjønt.

Svarte 05/12/2008 kl. 02:55
kilden bruker

stemmer
1

Hvis du bare prøver å se om et bestemt ord som finnes i ordlisten (det vil si, det er stavet riktig), så jeg tror ikke et binært søketre er det du leter etter. En bedre måte å lagre denne informasjonen ville være i et tre stil der hver påfølgende node på treet er ett tegn, og lese banen til endenode gir deg staving av ordet. Du vil også må legge til en markør for å indikere et ord-ending.

F.eks: si ordlisten har disse ordene: bil, vogn, katt, cup, kutt

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

Sjekke om et ord som finnes er et spørsmål om å se på hver bokstav individuelt, og at den finnes i barn av den aktuelle noden.

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.

Hvordan du lagrer denne informasjonen er opp til deg. Som Steven påpekt, en trefoldig Søk Trie kan være veien å gå: hver node vil ha 27 mulige barn noder.

Svarte 05/12/2008 kl. 03:16
kilden bruker

stemmer
3

Er du død-set på å bruke et binært søketre? En Bloom filter ville sannsynligvis være en mer effektiv datastruktur.

Svarte 05/12/2008 kl. 03:34
kilden bruker

stemmer
0

Å se at dette er en lekser spørsmål jeg kommer til å anta at du må bruke en vanlig gammel binært tre (ingen rød-svart trær, AVL trær, Radix trær, etc.). Svaret er da å prøve å holde treet balansert som du bygger det fra ordlisten. En tilnærming er å random listen før du leser den i gir dette rimelige resultater. Men du kan få bedre resultater hvis du bestiller inngangssekvensen (med de samme forhold som det treet bruker), deretter rekursivt dele inngangs retur midtpunktet til ingen elementer gjenstår. Resultatet er en balansert tre.

Jeg banket opp tre forskjellige måter å gjøre det i 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);
}
Svarte 20/04/2011 kl. 20:27
kilden bruker

stemmer
1

Dette nettstedet skal hjelpe deg det har implementeringen i java.

Svarte 12/06/2011 kl. 03:07
kilden bruker

stemmer
0

Som foreslått en trie ville være mer effektivt enn et binært tre, men du kan bruke en HashMap og hasj hvert ord. Du har en liten ordbok (1000 oppføringer). Som du krysse dokumentet, sjekk om ordene er i HashMap. Hvis de ikke er ordet antas å være feilstavet.

Dette vil ikke gi deg mulig korreksjon til et feilstavet ord. Det bare forteller deg ja eller nei (riktig eller ikke).

Hvis du vil ha forslag til stavemåter for feil ord kan du starte fra ordet i filen, deretter generere alle ord en redigerings stykke unna, og legge disse som barn av den opprinnelige ordet. Denne måten du bygger en graf. Gå 2 nivåer dyp for maksimal hastighet vs nøyaktighet. Hvis du genererer et ord node som er i ordlisten, kan du legge det til en liste over mulige forslag. På slutten, returnerer listen over mulige forslag.

For bedre stavekontroll, også prøve å legge i fonetisk matching.

sjø yuh -> se yah

Denne metoden (for å lage grafiske fremstillinger av strenger 1 redigering unna) er "langsom". Men det er en god akademisk øvelse. Kjøretids er O (n ^) grener.

Hvis interessert her er en link til en jeg bygget meg (for moro): https://github.com/eamocanu/spellcheck.graph

Noen eksempler på grafer: https://github.com/eamocanu/spellcheck.graph/tree/master/graph%20photos

Jeg har også lagt en UI komponent til det som genererer grafene. Dette er en ekstern bibliotek.

Svarte 15/12/2011 kl. 21:26
kilden bruker

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