vb@rchiv
VB Classic
VB.NET
ADO.NET
VBA
C#
SEPA-Dateien erstellen inkl. IBAN-, BLZ-/Kontonummernprüfung  
 vb@rchiv Quick-Search: Suche startenErweiterte Suche starten   Impressum  | Datenschutz  | vb@rchiv CD Vol.6  | Shop Copyright ©2000-2025
 
zurück

 Sie sind aktuell nicht angemeldet.Funktionen: Einloggen  |  Neu registrieren  |  Suchen

VB.NET - Ein- und Umsteiger
Re: Wortliste, Datenmenge reduzieren 
Autor: ErfinderDesRades
Datum: 14.07.14 08:05

ah - ok.

dafür hab ich hab mal eine Baumstruktur erfunden, die die Worte Zeichenweise analysiert hat.

ach - ich hab da sogar ein wortreiches Readme zu verfasst:

Readme schrieb:
Zitat:

Ich kannjamal spaßeshalber versuchen, das Konzept des DictTrees zu verdeutlichen.

Der witz an der Sache ist, dass die Worte des Wörterbuchs übherhaupt nicht mehr als Strings erkennbar sind, sondern es werden nur noch einzelne Chars betrachtet.
Das passt ausgezeichnet zur Matrix, die ja auch keine Worte enthält, sondern 4 * 4 Chars - die Worte sind erst draus zu basteln.

Also einzulesen seien die Worte:
einer, einerlei, eingegrenzt, esel
die werden in chars zerlegt folgendermaßen im Tree abgelegt:
  s  e  l
 /
e  i  n  e  r  l  e  i
       \
        g  e  g  r  e  n  z  t
es gibt also 2 Verzweigungen, und "einer" ist gradezu verschwunden, denn es ist vollständig in "einerlei" enthalten.
Um diesem "verschwinden" entgegenzuwirken, wird das letzte Zeichen eines Wortes markiert:
  s  e  l!
 /
e  i  n  e  r! l  e  i!
       \
        g  e  g  r  e  n  z  t!
Ich denke, ist intuitiv erkennbar, dass die 4 worte korrekt abgebildet sind (gewissermaßen redundanzfrei).
Wenn man das vorwärts durchlaufend durchdenkt, bekommt man aber ein problem, die 4 Worte wieder zurückzubilden. Man läuft mw. das "einerlei" entlang, sammelt die Zeichen auf, und findet bei r!: hier ist ein Wort vollständig. Aber dass es noch weitergeht, bedeutet: wir habens hier mit 2 worten zu tun - aber nur die Zeichen eines Wortes eingesammelt! Eigentlich müsste man nun zurücklaufen, und das Wort "einer" verdoppeln, um dann mit einem der beiden Worte fortzufahren, bis man auch das "einerlei" hat.

Kultig wäre doch nun, wenn man statt von links nach rechts, den Baum von rechts nach links durchwandert. Dann kann man bei jeder !-Markierung eine Zeichen-Sammlung beginnen, und endet am Root "e" in 4 Strängen:
lese
ielrenie
renie
tznergegnie

Jo, das sind genau die 4 worte des Wörterbuchs, was sonst.

praktisch ist das in einer Rekursion verblüffend einfach umzusetzen:
nämlich anstatt bei der in die Tiefe absteigenden Rekursion kann man ebensogut auch einsammeln bei der aus der Tiefe zurückkehrenden Rekursion.
Eine gradezu lächerlich einfache Umstellung im Code implementiert das:

Statt:
Sub Enumerate(nd)
   collectChar(nd)
   For Each ndChild in nd.Children
      Enumerate(ndChild)
   Next
End Sub
schreibe man:
Sub Enumerate(nd)
   For Each ndChild in nd.Children
      Enumerate(ndChild)
   Next
   collectChar(nd)
End Sub
gesehen? Der NutzCode "collectChar(nd)" des Knoten-Besuchs ist einfach hinter dem Selbst-Aufruf plaziert. Dadurch wird der aktuelle Knoten nicht ausgewertet, bevor die Kinder besucht werden, sondern die Kinder sind bereits besucht und ausgewertet, wenn der aktuelle Knoten zur Auswertung gelangt.
Jetzt ist es also ein leichtes, beim Antreffen eines WortEndes einen zusätzlichen Sammel-Strang zu eröffnen, sodass man am Ende 4-strängig im root ankommt (zurückkehrt, um genau zu sein - es ist ja eine "re"kursion).

Aber wir packen ja nicht idiotischerweise alle Wörter in den dictTree, nur um sie anschließend wieder rekursiv zu rekonstruieren. Nein, bei Enumerate(ByVal pt As MatrixPoint, ByVal dic As DictNode) handelt es sich um zwei rekursive Durchläufe, die miteinander synchronisiert sind.
Das eine ist die Matrix, deren gültige Pfade rekursiv abgelatscht werden. Das andere ist der DictTree, und der gibt der Matrix-Rekursion an "wos lang geht": Nämlich in der Matrix darf nur dahin ein Schritt erfolgen, wo man auch im DictTree einen "parallelen" Schritt tun kann:

If dic.TryGetValue(ptChild.Letter, dicChild) Then
(Selbstaufruf(ptChild, dicChild))

hier versucht das Dictionary dic, den Schritt nach dicChild zu gehen: es wird geguckt, ob unter dem Schlüssel ptChild.Letter ein Eintrag im Dictionary(of Char, dictNode) vorhanden ist.
Ist der Schritt erfolgreich, dann erfolgt der Selbst-Aufruf, mit dem sowohl der dictNode als auch der aktuelle MatrixPoint "ptParent" ihren ChildNode in den Selbstaufruf geben, und die Rekursion also um eine Ebene vertiefen.

Der Rest wurde ja oben schon genannt: das einsammeln der Chars im aufsteigenden Rekursions-Ast, und auch das Hinzufügen eines Sammel-Stranges, wenn eine WortEnde-Markierung aufgefunden wird. Ist auch im Source klar erkennbar und kommentiert:
   'im wieder-aufstieg: neue Result-Liste eröffnen, wenn Wortende angetroffen
   If dic.WordEnd Then res.Add(New List(Of Char))
   'aktuellen Char in alle Result-Listen eintraten
   For Each r In res
      r.Add(pt.Letter)
   Next
   pt.Touched = False '"Betreten"-Markierung aufheben
   Return res
End Function
jo, ich kann dir das Teil auch per email schicken

(Rechtschreibfehler urheberrechtlich geschützt)

alle Nachrichten anzeigenGesamtübersicht  |  Zum Thema  |  Suchen

 ThemaViews  AutorDatum
Wortliste, Datenmenge reduzieren1.753DotNetErbse12.07.14 11:56
Re: Wortliste, Datenmenge reduzieren1.132ErfinderDesRades12.07.14 21:47
Re: Wortliste, Datenmenge reduzieren1.128DotNetErbse14.07.14 07:41
Re: Wortliste, Datenmenge reduzieren1.260ErfinderDesRades14.07.14 08:05
Re: Wortliste, Datenmenge reduzieren1.090DotNetErbse14.07.14 09:16
Re: Wortliste, Datenmenge reduzieren1.087Manfred X14.07.14 10:41
Re: Wortliste, Datenmenge reduzieren1.066DotNetErbse14.07.14 14:40
Re: Wortliste, Datenmenge reduzieren1.044Manfred X14.07.14 22:37
Re: Wortliste, Datenmenge reduzieren1.117DotNetErbse16.07.14 07:47

Sie sind nicht angemeldet!
Um auf diesen Beitrag zu antworten oder neue Beiträge schreiben zu können, müssen Sie sich zunächst anmelden.

Einloggen  |  Neu registrieren

Funktionen:  Zum Thema  |  GesamtübersichtSuchen 

nach obenzurück
 
   

Copyright ©2000-2025 vb@rchiv Dieter Otter
Alle Rechte vorbehalten.
Microsoft, Windows und Visual Basic sind entweder eingetragene Marken oder Marken der Microsoft Corporation in den USA und/oder anderen Ländern. Weitere auf dieser Homepage aufgeführten Produkt- und Firmennamen können geschützte Marken ihrer jeweiligen Inhaber sein.

Diese Seiten wurden optimiert für eine Bildschirmauflösung von mind. 1280x1024 Pixel