sql >> Database teknologi >  >> RDS >> Mysql

Scrabble ordfinder med jokertegn

Det gør du ikke. En relationel databasetabel er ikke en egnet datastruktur til at løse dette problem så effektivt, som du har brug for.

Det du gør i stedet er, at du bygger en forsøg datastruktur ud af ordbogen (eller, hvis du er virkelig vild, bygger du en dawg -- en rettet acyklisk ordgraf -- som er en slags komprimeret prøve.)

Når du først har en trie/dawg, bliver det meget billigt at teste hver ord i ordbogen mod et givet stativ, fordi du kan "beskære" hele enorme grene af ordbogen, som stativet umuligt kan matche.

Lad os se på et lille eksempel. Antag, at du har ordbogen "OP, OPS, OPT, OPTS, POT, POTS, SOP, SOPS, STOP, STOPS" Ud fra det bygger du denne prøve:(Noder med en $ er dem, der er markeret som "ord kan ende her" .

^root^ / | \ O P S | | / \ P$ O O T / \ | | | T$ S$ T$ P$ O | | | | S$ S$ S$ P$ | S$

og du har stativet "OPS" -- hvad gør du?

Først siger du "kan jeg gå ned ad O-grenen?" Ja du kan. Så nu er problemet at matche "PS" mod O-grenen. Kan du gå ned i P-undergrenen? Ja. Har den en slutningsmarkør? Ja, så OP er et match. Nu er problemet at matche "S" mod OP-grenen. Kan du gå ned af T-grenen? Nej. Kan du gå ned af S-grenen? Ja. Nu har du det tomme stativ, og du skal matche det mod OPS-grenen. Har den en slut-på-ord-markør? Ja! Så OPS matcher også. Gå nu tilbage til roden.

Kan du gå ned af P-grenen? Ja. Nu er problemet at matche OS mod P-grenen. Gå ned i PO-grenen og match S -- det mislykkes. Gå tilbage til roden.

Og igen, du kan se, hvordan det går. Til sidst går vi ned i SOP-grenen og finder en slutning på SOP, så "SOP" matcher dette stativ. Vi går ikke ned af ST-grenen, fordi vi ikke har et T.

Vi har prøvet alle mulige ord i ordbogen og opdaget, at OP, OPS og SOP alle matcher. Men vi behøvede aldrig at undersøge OPTS, POTS, STOP eller STOPS, fordi vi ikke havde et T.

Kan du se, hvordan denne datastruktur gør den meget effektiv? Når du har fastslået, at du ikke har bogstaverne på stativet for at begynde af et ord, behøver du ikke at undersøge noget ordbogsord, der starter med den begyndelse. Hvis du har PO, men intet T, behøver du ikke at undersøge POTSSHRD eller POTAFO eller POTASH eller POTLATCH eller POTABLE; alle de dyre og frugtesløse søgninger forsvinder meget hurtigt.

At tilpasse systemet til at håndtere "vilde" fliser er ret ligetil; hvis du har OPS?, så kør bare søgealgoritmen 26 gange, på OPSA, OPSB, OPSC... Det burde være hurtigt nok til, at det er billigt at gøre det 26 gange (eller gøre det 26 x 26 gange, hvis du har to blanks. )

Dette er den grundlæggende algoritme, som professionelle Scrabble AI-programmer bruger, selvom de selvfølgelig også skal håndtere ting som bestyrelsesposition, rack management og så videre, hvilket komplicerer algoritmerne noget. Denne enkle version af algoritmen vil være meget hurtig nok til at generere alle de mulige ord på et stativ.

Glem ikke, at du selvfølgelig kun skal beregne trie/dawg én gang hvis ordbogen ikke ændrer sig over tid. Det kan være tidskrævende at bygge prøven ud af ordbogen, så du vil måske gøre det en gang og find derefter ud af en måde at gemme prøven på disken i en form, der er egnet til at genopbygge den hurtigt fra disken.

Du kan optimere hukommelsesforbruget ved at bygge en DAWG ud af forsøget. Læg mærke til, at der er mange gentagelser, for på engelsk er mange ord slut det samme, ligesom mange ord begynder det samme. Trie gør et godt stykke arbejde med at dele noder i begyndelsen, men et elendigt stykke arbejde med at dele dem i slutningen. Du kan f.eks. bemærke, at mønsteret "S$ uden børn" er ekstremt almindeligt, og gør forsøget til:

^root^ / | \ O P S | | / \ P$ O O T / \ | | | T$ | T$ P$ O | \ | | | \ \| / P$ \ |/ | \ | / \ | / \ | / \| / |/ | S$

Gemmer en hel bunke noder. Og så vil du måske bemærke, at to ord nu ender på O-P$-S$, og to ord ender på T$-S$, så du kan komprimere det yderligere til:

^root^ / | \ O P S | | / \ P$ O \ T / \| \ | | | \| | | O | T$ | \ | P$ \ | / \| / | / |/ S$

Og nu har vi den minimale DAWG til denne ordbog.

Yderligere læsning:

http://dl.acm.org/citation.cfm?id=42420

http://archive.msdn.microsoft.com/dawg1

http://www.gtoal.com/wordgames/scrabble.html



  1. MS SQL PÅ SLET CASCADE flere fremmednøgler, der peger på den samme tabel?

  2. codeigniter active record få forespørgsel og forespørgsel uden LIMIT-klausulen

  3. Jeg vil indsætte data i mysql-databasen ved hjælp af PDO fra PHP. Men dataene er ikke indsat

  4. Kortlægning af sammensatte nøgler ved hjælp af EF-kode først