Πέμπτη 2 Ιουλίου 2026

Suffix Tree (updated)

This is a Greek variation of the suffix tree (using greek M2000 statements). I change a little the tree, plus I put some code for export to printer (default the pdf printer):

The image show ta cropped window of the M2000 console plus the Sumatra pdf viewer::




'https://rosettacode.org/wiki/Suffix_tree
ΤΜΗΜΑ Παράδειγμα_Δένδρο_Καταλήξεων {
  ΚΛΑΣΗ Δένδρο_Καταλήξεων {
  ΙΔΙΩΤΙΚΟ:
    Κόμβοι=ΛΙΣΤΑ
    ' ΚΛΑΣΗ ορισμός που επιστρέφει δείκτη σε αντικείμενο
    ' και όχι τιμή αντικείμενο (αυτά διαφέρουν στη Μ2000)
    ΚΛΑΣΗ Κόμβος {
      ΓΡΑΜΜΑ Κατάληξη
      Γράμματα=ΛΙΣΤΑ
      {
        ΔΙΑΒΑΣΕ Κόμβος.Κατάληξη, Κόμβος.Γράμματα
        ->(Κόμβος)
        ΔΙΕΚΟΨΕ
      }
    }
    ΤΜΗΜΑ ΠρόσθεσεΚατάληξη (Κατάληξη1 ΩΣ ΓΡΑΜΜΑ) {
      ΜΑΚΡΥΣ ν = 0, ι = 0, χ2, ν2
      ΓΡΑΜΜΑ β
      ΕΝΩ ι < ΜΗΚΟΣ(Κατάληξη1)
        β=ΜΕΣ(Κατάληξη1,ι+1,1)
        χ2=0
        ν2=0
        ΕΠΑΝΑΛΑΒΕ ' Δουλεύει και το ΕΠΑΝΕΛΑΒΕ
          Παιδιά=.Κόμβοι(ν).Γράμματα
          ΑΝ χ2=ΜΗΚΟΣ(Παιδιά) ΤΟΤΕ
            ν2=ΜΗΚΟΣ(.Κόμβοι)
            ' αν δεν είχαμε παρενθέσεις θα βάζαμε το <=
            ' αλλιώς η Μ2000 φτιάχνει τοπική..με το ίδιο όνομα
            .Κόμβοι(ν2)=.Κόμβος(ΜΕΣ(Κατάληξη1, ι+1))
            Παιδιά(χ2)=ν2
            ΔΙΕΚΟΨΕ ' Έξοδος από το ΤΜΗΜΑ
          ΤΕΛΟΣ ΑΝ
          ν2=Παιδιά(χ2)
          ΑΝ ΑΡΙΣ(.Κόμβοι(ν2).Κατάληξη,1)=β ΤΟΤΕ ΕΞΟΔΟΣ ' Έξοδος ΕΠΑΝΑΛΑΒΕ
          χ2++
        ΠΑΝΤΑ
        Δευτερεύουσα=.Κόμβοι(ν2).Κατάληξη
        ΜΑΚΡΥΣ κ=0
        ΕΝΩ κ < ΜΗΚΟΣ(Δευτερεύουσα)
          ΑΝ ΜΕΣ(Κατάληξη1,ι+1+κ,1)<>ΜΕΣ(Δευτερεύουσα, κ+1,1) ΤΟΤΕ
            n3=ν2
            ν2=ΜΗΚΟΣ(.Κόμβοι)
            .Κόμβοι(ν2)=.Κόμβος(ΑΡΙΣ(Δευτερεύουσα,κ), ΛΙΣΤΑ:=0:=n3)
            .Κόμβοι(n3).Κατάληξη=ΜΕΣ(Δευτερεύουσα, κ+1)
            .Κόμβοι(ν).Γράμματα(χ2)=ν2
            ΕΞΟΔΟΣ
          ΤΕΛΟΣ ΑΝ
          κ++
        ΤΕΛΟΣ ΕΝΩ
        ι+=κ
        ν=ν2
      ΤΕΛΟΣ ΕΝΩ
    }
  ΔΗΜΟΣΙΟ:
    ΤΜΗΜΑ Επίδειξη {
      ΑΝ ΜΗΚΟΣ(.Κόμβοι)=0 ΤΟΤΕ ΤΥΠΩΣΕ "<κενό>":ΕΞΟΔΟΣ
      Ανάδειξε 0, ""    
      ΡΟΥΤΙΝΑ Ανάδειξε(ν ΩΣ ΜΑΚΡΥΣ, Πρόσθετο ΩΣ ΓΡΑΜΜΑ)
        ΤΟΠΙΚΗ Παιδιά=.Κόμβοι(ν).Γράμματα
        ΑΝ ΜΗΚΟΣ(Παιδιά)=0 ΤΟΤΕ
          ΤΥΠΩΣΕ "─ "+.Κόμβοι(ν).Κατάληξη
        ΑΛΛΙΩΣ
          ΤΥΠΩΣΕ "┐ "+.Κόμβοι(ν).Κατάληξη
          ΕμφάνισεΚλάδο ΚΑΘΕ(Παιδιά, 1 , -2), "├─"
          ΕμφάνισεΚλάδο ΚΑΘΕ(Παιδιά, -1), "└─"
        ΤΕΛΟΣ ΑΝ
      ΤΕΛΟΣ ΡΟΥΤΙΝΑΣ
      ΡΟΥΤΙΝΑ ΕμφάνισεΚλάδο(Γράμματα, Πρόσθετο2 ΩΣ ΓΡΑΜΜΑ)
        ΕΝΩ Γράμματα
          ΤΥΠΩΣΕ Πρόσθετο + Πρόσθετο2;
          Ανάδειξε ΕΚΦΡ(Γράμματα), Πρόσθετο + "│ "
        ΤΕΛΟΣ ΕΝΩ
      ΤΕΛΟΣ ΡΟΥΤΙΝΑΣ
    }
    ΙΔΙΟΤΗΤΑ Μήκος {
        ΑΞΙΑ {
            ΕΝΩΣΕ ΓΟΝΙΚΟ Κόμβοι ΣΤΟ Κ
            ΑΞΙΑ=ΜΗΚΟΣ(Κ)
        }
    }=0
    ΙΔΙΟΤΗΤΑ Όρισμα {
       ΑΞΙΑ
    }=""
    ΑΞΙΑ (Αρ) {
      =""
      Δες {
          =.Κόμβοι(Αρ).Κατάληξη
      }
    }
    θΕΣΕ (Όρισμα1 ΩΣ ΓΡΑΜΜΑ) {
      ΑΝ ΜΗΚΟΣ(Όρισμα1)=0 ΤΟΤΕ ΛΑΘΟΣ "χρειάζομαι ένα χαρακτήρα τουλάχιστον"
      .[Όρισμα]<=Όρισμα1
      .Κόμβοι<=ΛΙΣΤΑ
      .Κόμβοι(0)=.Κόμβος()
      ΓΙΑ ι=1 ΕΩΣ ΜΗΚΟΣ(Όρισμα1)
        .ΠρόσθεσεΚατάληξη ΜΕΣ(Όρισμα1, ι)
      ΕΠΟΜΕΝΟ
    }
  }
  Δένδρο_Καταλήξεων Μ = "banana$", Μ2 = "ΠΑΠΑΚΙ$"
  Μ.Επίδειξη
  Μ="ΠΑΤΑΤΑΚΙΑ$"  ' αλλαγή πίνακα
  Μ.Επίδειξη
  ΤΥΠΩΣΕ "Μ2=";ΠΑΡΑΘΕΣΗ$(Μ2.Όρισμα) 'βάζει εισαγωγικά
  ΓΙΑ Κ=1 ΕΩΣ Μ2.Μήκος-1
    ΤΥΠΩΣΕ "(";Κ;") "; Μ2(Κ)
  ΕΠΟΜΕΝΟ
  Μ2.Επίδειξη
}
ΓΡΑΜΜΑΤΟΣΕΙΡΑ "Courier New"
ΦΟΡΜΑ 80, 66
ΔΙΑΒΑΣΕ με_εκτύπωση=ΨΕΥΔΕΣ
ΑΝ με_εκτύπωση ΤΟΤΕ
  ΕΚΤΥΠΩΣΗ ΝΑΙ : ΠΕΝΑ 0 ' ΜΑΥΡΟ
  ΓΡΑΜΜΑΤΟΣΕΙΡΑ "Courier New"
  ΦΟΡΜΑ 80, 66


ΑΛΛΙΩΣ
  ΟΘΟΝΗ 15: ΠΕΝΑ 0
ΤΕΛΟΣ ΑΝ
Παράδειγμα_Δένδρο_Καταλήξεων
ΑΝ με_εκτύπωση ΤΟΤΕ
  ΕΚΤΥΠΩΣΗ ΟΧΙ
ΑΛΛΙΩΣ
  ' ΠΑΤΑ ΕΝΑ ΠΛΗΚΤΡΟ
  ΒΑΛΕ ΚΟΜ$:ΠΕΤΑ
ΤΕΛΟΣ ΑΝ





https://rosettacode.org/wiki/Suffix_tree#M2000_Interpreter

https://en.wikipedia.org/wiki/Suffix_tree


'https://rosettacode.org/wiki/Suffix_tree
Module Suffix_tree {
  Class SuffixTree {
  Private:
    Nodes=List
    ' Class definition which return a pointer to object
    Class Node {
      String sub
      ch=list
      {
        Read Node.sub, Node.ch
        ->(Node)
        break
      }
    }  
    module addSuffix (suf as String) {
      long n = 0, i = 0, x2, n2
      String b
      While i < Len(suf)
        b=mid(suf,i+1,1)
        x2=0
        n2=0
        do
          children=.Nodes(n).ch
          if x2=len(children) Then
            n2=len(.Nodes)
            .Nodes(n2)=.Node(Mid$(suf, i+1))
            children(X2)=n2
            break ' Exit module
          End if
          n2=children(x2)
          if left(.Nodes(n2).sub,1)=b Then Exit ' Exit do
          x2++      
        Always
        sub2=.Nodes(n2).sub
        long j=0
        While j<len(sub2)      
          if mid(suf,i+1+j,1)<>mid(sub2, j+1,1) Then
            n3=n2
            n2=len(.Nodes)
            .Nodes(n2)=.Node(Left(sub2,j), List:=0:=n3)
            .Nodes(n3).sub=Mid(sub2, j+1)
            .Nodes(n).ch(X2)=n2
            Exit
          End if
          j++
        End While
        i+=j
        n=n2
      End While
    }    
  Public:
    module visualize {
      if len(.Nodes)=0 Then ? "<empty>":Exit
      visualize_f(0, "")    
      sub visualize_f(n as long, pre as string)
        Local children=.Nodes(n).ch
        if len(children)=0 Then
          ? "- "+.Nodes(n).sub
        Else
          ? "┐ "+.Nodes(n).sub
          Pr each(children, 1 , -2), "├─"
          Pr each(children, -1), "└─"
        End if
      End sub
      Sub Pr(ch, pre2 as string)
        While ch  
        ? pre + pre2;
        visualize_f(Eval(ch), pre + "│ ")
        End While
      End Sub
    }
  Class:
    module SuffixTree (Str as String) {
      if len(Str)=0 Then Error "need one character...at least"
      .Nodes(0)=.Node()
      for i=1 to len(Str)
          .addSuffix Mid(Str, i)
      next
    }
  }
  M=SuffixTree("banana$")
  M.visualize
}
Suffix_tree

Δεν υπάρχουν σχόλια:

Δημοσίευση σχολίου

You can feel free to write any suggestion, or idea on the subject.