KeyTree - Schlüsselwörter mit Daten

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
Benutzeravatar
Josef Sniatecki
Beiträge: 657
Registriert: 02.06.2008 21:29
Kontaktdaten:

KeyTree - Schlüsselwörter mit Daten

Beitrag von Josef Sniatecki »

Ich habe mal ein Template geproggt, mit dem man Schlüsselwörter
mit angehängten Daten verwalten kann.

Vorteil:
Hier werden nicht die Schlüsselwörter + Daten in eine Liste abgespeichert,
sondern in einen Datenbaum. Damit ist die schnelligkeit des Zugriffes
nur von der Länge eines Schlüsselwortes abhängig und nicht von der
Anzahl der Schlüsselwörter.

Nachteil:
Für jeden neuen Buchstabe in einer Ebene werden (26 + 2) * Long Bytes
benötigt. Bei 100 Wörtern kann das ein bisschen viel werden.

Hier ist der Code + Beispiel:

Code: Alles auswählen

;/-----------------------------------------------------------------\
;|  *** KeyTree - template ***                                     |
;|    Created by Josef Sniatecki 2008.                             |
;\-----------------------------------------------------------------/



;/------------------------------------------\
;| Structures                               |
;\------------------------------------------/

Structure KeyTree
  *Mem     ;Memory
  CharAm.l ;CharacterAmount
  *A.KeyTree
  *B.KeyTree
  *C.KeyTree
  *D.KeyTree
  *E.KeyTree
  *F.KeyTree
  *G.KeyTree
  *H.KeyTree
  *I.KeyTree
  *J.KeyTree
  *K.KeyTree
  *L.KeyTree
  *M.KeyTree
  *N.KeyTree
  *O.KeyTree
  *P.KeyTree
  *Q.KeyTree
  *R.KeyTree
  *S.KeyTree
  *T.KeyTree
  *U.KeyTree
  *V.KeyTree
  *W.KeyTree
  *X.KeyTree
  *Y.KeyTree
  *Z.KeyTree
EndStructure



;/------------------------------------------\
;| Functions                                |
;\------------------------------------------/

Procedure.l KeyTree()
  ProcedureReturn AllocateMemory(SizeOf(KeyTree))
EndProcedure
Procedure.l KeyTreeKey(*KeyTree.KeyTree,Key.s,*Mem)
  ;KeyTreeKey(Key,Memory)
  ;{
  ;  Fügt ein neues Schlüsselwort[Key] mit angegebenen
  ;  Daten[Mem] in ein KeyTree ein.
  ;}
  
  Protected *Char.Character ;Character
  Protected *CKeyTree.KeyTree     ;CurrentKeyTree
  
  *Char=@Key
  *CKeyTree=*KeyTree
  While *Char\C<>0
    If PeekL(*CKeyTree+8+(*Char\C-65)*SizeOf(Long))=0 ;Buchstabe noch nicht im KeyTree vorhanden...
      *CKeyTree\CharAm+1
      PokeL(*CKeyTree+8+(*Char\C-65)*SizeOf(Long),AllocateMemory(SizeOf(KeyTree)))
    EndIf
    *CKeyTree=PeekL(*CKeyTree+8+(*Char\C-65)*SizeOf(Long))
    *Char+1
  Wend
  
  If *CKeyTree\Mem=0
    *CKeyTree\Mem=*Mem
    ProcedureReturn *CKeyTree
  Else
    CompilerIf #PB_Compiler_Debugger
      Debug "KeyTreeKey()-error: "+Key+" is already in the KeyTree."
      Beep_(250,250)
      End
    CompilerElse
      ProcedureReturn #False
    CompilerEndIf
  EndIf
EndProcedure
Procedure.l KeyTree_Mem(*KeyTree.KeyTree,Key.s)
  ;KeyTree_Memory(KeyTree,Key)
  ;{
  ;  Gibt die Datei zurück, die dem
  ;  Schlüsselwort[Key] zugewiesen wurde.
  ;}
  
  Protected *Char.Character ;Character
  Protected *CKeyTree.KeyTree     ;CurrentKeyTree
  
  *Char=@Key
  *CKeyTree=*KeyTree
  While *Char\C<>0
    If PeekL(*CKeyTree+8+(*Char\C-65)*SizeOf(Long))
      *CKeyTree=PeekL(*CKeyTree+8+(*Char\C-65)*SizeOf(Long))
    Else
      CompilerIf #PB_Compiler_Debugger
        Debug "KeyTree_Mem()-error: "+Key+" is not in the KeyTree."
        Beep_(250,250)
        End
      CompilerElse
        ProcedureReturn #False
      CompilerEndIf
    EndIf
    *Char+1
  Wend
  
  ProcedureReturn *CKeyTree\Mem
EndProcedure
Procedure.l DelKeyTreeKey(*KeyTree.KeyTree,Key.s,DelMem.b=#True)
  ;DeleteKeyTreeKey(KeyTree,Key,DeleteMemory=#True)
  ;{
  ;  Löscht das Schlüsselwort[Key] aus
  ;  dem KeyTree. Wenn [DelMem] auf 1 gesetzt ist, so
  ;  werden auch die zugewiesenen Daten gelöscht.
  ;}
  
  Protected *Char.Character ;Character
  Protected *CKeyTree.KeyTree     ;CurrentKeyTree
  Protected *NKeyTree.KeyTree     ;NextKeyTree
  Protected *RetMem         ;ReturnMemory
  
  *Char=@Key
  *CKeyTree=*KeyTree
  While *Char\C<>0
    If PeekL(*CKeyTree+8+(*Char\C-65)*SizeOf(Long))
      *NKeyTree=PeekL(*CKeyTree+8+(*Char\C-65)*SizeOf(Long))
      If *NKeyTree\CharAm=1
        PokeL(*CKeyTree+8+(*Char\C-65)*SizeOf(Long),0)
        *CKeyTree\CharAm-1
        If *CKeyTree\CharAm=0 And *CKeyTree<>*KeyTree
          If FreeMemory(*CKeyTree)=#False
            ProcedureReturn #False
          EndIf
        EndIf
      EndIf
      *CKeyTree=*NKeyTree
    Else
      CompilerIf #PB_Compiler_Debugger
        Debug "DelKeyTreeKey()-error: "+Key+" is not in the KeyTree."
        Beep_(250,250)
        End
      CompilerElse
        ProcedureReturn #False
      CompilerEndIf
    EndIf
    *Char+1
  Wend
  
  If DelMem=#True
    If DelMem
      If FreeMemory(*CKeyTree\Mem)=#False
        ProcedureReturn #False
      EndIf
    EndIf
  EndIf
  
  If *CKeyTree\CharAm=1
    If DelMem=#False
      *RetMem=*CKeyTree\Mem
    EndIf
    If FreeMemory(*CKeyTree)
      ProcedureReturn *RetMem
    Else
      ProcedureReturn #False
    EndIf
  Else
    *CKeyTree\CharAm-1
    *RetMem=*CKeyTree\Mem
    *CKeyTree\Mem=0
    ProcedureReturn *RetMem
  EndIf
EndProcedure



;/------------------------------------------\
;| Examples                                 |
;\------------------------------------------/

Global *MyKeyTree.KeyTree=KeyTree()     ;Erstellt ein neues KeyTree.
KeyTreeKey(*MyKeyTree,"MYNAME",?MyName) ;Fügt ein Schlüsselwort mit der Datei "?MyName" ein.
KeyTreeKey(*MyKeyTree,"SOURCE",?Source)
KeyTreeKey(*MyKeyTree,"OS",?OS)

Debug "MYNAME : "       +PeekS(KeyTree_Mem(*MyKeyTree,"MYNAME")) ;Ließt ein String aus
Debug "SOURCE : "       +PeekS(KeyTree_Mem(*MyKeyTree,"SOURCE")) ;der Datei des Schlüsselwortes.
Debug "OS : "           +PeekS(KeyTree_Mem(*MyKeyTree,"OS"))
Debug "direct SOURCE : "+PeekS(*MyKeyTree\S\O\U\R\C\E\Mem)       ;Direkter zugriff.

DelKeyTreeKey(*MyKeyTree,"SOURCE",0)          ;Löscht "SOURCE" aus dem KeyTree.
Debug PeekS(KeyTree_Mem(*MyKeyTree,"SOURCE")) ;Gibt eine Warnung. (Nur wenn Debugger an ist!)

DataSection
  MyName: Data.s "Josef Sniatecki"
  Source: Data.s "KeyTree - template"
  OS:     Data.s "Windows XP"
EndDataSection
Leider ist es nur möglich Schlüsselwörter mit Großbuchstaben zu
erstellen. Es ist auch nicht möglich irgendwelche Sonderzeichen oder
Leerzeichen zu nutzen. Auch ein Unterstrich ist nicht erlaubt.
PB 4.61 | Windows Vista - 32Bit
Homepage

"Wahrlich es ist nicht das Wissen, sondern das Lernen, nicht das Besitzen sondern das Erwerben, nicht das Dasein, sondern das Hinkommen, was den grössten Genuss gewährt." - Carl Friedrich Gauß
Benutzeravatar
Josef Sniatecki
Beiträge: 657
Registriert: 02.06.2008 21:29
Kontaktdaten:

Beitrag von Josef Sniatecki »

Ich habe den ersten Beitrag geändert. Vorher habe ich mein Template
Hash genannt. Eigentlich ist das ja falsch. Hashes stellen eine Konkurrenz
für B*-Bäume. Und mein Template basierte auf einem B*-Baum. :oops:
Hier sind mehr infos: http://de.wikipedia.org/wiki/Hashtabelle
PB 4.61 | Windows Vista - 32Bit
Homepage

"Wahrlich es ist nicht das Wissen, sondern das Lernen, nicht das Besitzen sondern das Erwerben, nicht das Dasein, sondern das Hinkommen, was den grössten Genuss gewährt." - Carl Friedrich Gauß
Antworten