Prefix Tree Traversal


13

Schreiben Sie ein Programm, das (über stdin oder die Befehlszeile) einen String mit der rekursiven Form aufnimmt

PREFIX[SUFFIXES]

wo

  • PREFIX kann eine beliebige Zeichenfolge aus Kleinbuchstaben (az) sein, einschließlich der leeren Zeichenfolge und
  • SUFFIXESkann eine beliebige Folge von Zeichenfolgen sein, bei denen die rekursive Form PREFIX[SUFFIXES]zusammengefügt ist, einschließlich der leeren Folge.

Erstellen Sie aus der Eingabe eine Liste von Zeichenfolgen mit Kleinbuchstaben, indem Sie die Liste der Zeichenfolgen in den einzelnen Suffixen rekursiv auswerten und an das Präfix anhängen. Ausgabe der Zeichenfolgen in dieser Liste in beliebiger Reihenfolge, eine pro Zeile (zuzüglich einer optionalen nachgestellten neuen Zeile).

Beispiel

Wenn der Eingang ist

cat[s[up[][]][]ch[e[r[]s[]]]a[maran[]comb[]pult[[]ing[]]]]

dann wird das Präfix ist catund und die Suffixe sind s[up[][]], [], ch[e[r[]s[]]], und a[maran[]comb[]pult[[]ing[]]]. Jedes Suffix hat sein eigenes Präfix und Suffixe.

Die Ausgabe würde diese 9 Wörter in beliebiger Reihenfolge sein

catsup
cats
cat
catcher
catches
catamaran
catacomb
catapult
catapulting

weil die Eingabe diesen Baum codiert

Baum diagramm

und jedes der 9 Ausgangswörter kann durch Überqueren des Baums von der Wurzel zum Blatt gebildet werden.

Anmerkungen

  • Denken Sie daran, dass das Präfix die leere Zeichenfolge sein kann, also so etwas wie

    [donut[][]cruller[]]
    

    ist eine gültige Eingabe, deren Ausgabe (in beliebiger Reihenfolge) wäre

    donut
    
    cruller
    

    Dabei steht die leere Zeile für die leere Zeichenfolge, mit der das zweite Suffix übereinstimmt.

  • Die Suffix-Sequenz kann auch leer sein, also der einfache Eingabefall

    []
    

    hat eine einzelne leere Zeile als Ausgabe:

    
    
  • Sie können davon ausgehen, dass die Eingabe nur eindeutige Ausgabewörter erzeugt.
    • zB hat[s[]ter[]s[]]wäre eine ungültige Eingabe, da hatsdoppelt codiert.
    • Ebenso [[][]]ist ungültig, da die leere Zeichenfolge zweimal codiert wird.
  • Sie können nicht davon ausgehen, dass die Eingabe so kurz oder komprimiert wie möglich ist.
    • Beispiel: Der 'e'Knoten im obigen Hauptbeispiel könnte mit dem 'ch'Knoten kombiniert werden. Dies bedeutet jedoch nicht, dass die Eingabe ungültig ist.
    • Ebenso [[[[[]]]]]ist gültig, obwohl nur die leere Zeichenfolge in einer suboptimalen Weise codiert wird.
  • Anstelle eines Programms können Sie eine Funktion schreiben, die die Eingabezeichenfolge als Argument verwendet und die Ausgabe normal ausgibt oder als Zeichenfolge oder Liste zurückgibt.

Der kürzeste Code in Bytes gewinnt.

Antworten:


2

Rubin, 119, 115

t=['']
l=[0]
gets.chars{|c|c<?]?t<<''&&(l<<0)[-2]+=1:c<?^?(x=l.pop;t.pop==''&&(puts t*''if x<1;t[-1]='')):t[-1]<<c}

Beispiel

Probieren Sie es aus: http://ideone.com/NW0CNB

Beschreibung

Das Programm erhält die Eingabe von stdin und gibt das Ergebnis an stdout aus.

Es durchläuft den Baum und hält den aktuellen Zweig in einem Stapel. Es gibt auch einen anderen Stapel, genanntweights der die Anzahl der Kinder jedes Knotens protokolliert. Dies ist erforderlich, um festzustellen, ob ein Knoten wirklich ein Blatt ist oder Kinder in der Vergangenheit hatte.

Das lesbare Programm:

stack = ['']
weights = [0]

gets.chars do |c|
  case c
  when '['
    weights[-1] += 1
    stack << ''
    weights << 0
  when ']'
    last_weight = weights.pop

    if stack.pop == ''
      puts stack.join if last_weight < 1
      stack[-1] = ''
    end
  else
    stack[-1] << c
  end
end

6

Haskell, 125 Bytes

t=tail.p
p=g.break(=='[')
g(a,(_:t))=(:)&(map(a++).z)$t#[]
z[]=[""];z x=x
(']':u)#a=u:a
s#a=(#)&(a++)$p s
(g&f)(x:y)=g x$f y

Die Funktion ist t(für Traversal):

λ: t "cat[s[up[][]][]ch[e[r[]s[]]]a[maran[]comb[]pult[[]ing[]]]]"
["catsup","cats","cat","catcher","catches","catamaran","catacomb","catapult","catapulting"]
λ: t "[donut[][]cruller[]]"
["donut","","cruller"]
λ: t "[[[[[]]]]]"
[""]

Ihr Code ist 124 Bytes, nicht 125 :)
Cristian Lupascu

Ich denke, das Muster (a,(_:t))kann (a,_:t)stattdessen sein
stolzer Haskeller

2

Java, 206 Bytes

Definiert eine Funktion, die eine Zeichenfolge als Argument akzeptiert und eine Liste von Zeichenfolgen zurückgibt. Für einen zusätzlichen Bonus werden die Zeichenfolgen in derselben Reihenfolge wie in der Frage zurückgegeben.

int c,i;List a(String a){String b=a.substring(c,c=a.indexOf(91,c));List d=new ArrayList();for(;a.charAt(++c)!=93;)d.addAll(a(a));if(d.isEmpty())d.add("");for(i=0;i<d.size();)d.set(i,b+d.get(i++));return d;}

Beispielverwendung:

class A{
    public static void main(String[] args){
        System.out.println(new A.a("cat[s[up[][]][]ch[e[r[]s[]]]a[maran[]comb[]pult[[]ing[]]]]"));
    }

    int c,i;List a(String a){String b=a.substring(c,c=a.indexOf(91,c));List d=new ArrayList();for(;a.charAt(++c)!=93;)d.addAll(a(a));if(d.isEmpty())d.add("");for(i=0;i<d.size();)d.set(i,b+d.get(i++));return d;}
}

Erweitert:

int c, i;
List a(String a){
    String b = a.substring(c, c = a.indexOf(91, c));
    List d = new ArrayList();
    for(; a.charAt(++c) != 93 ;)
        d.addAll(a(a));
    if (d.isEmpty())
        d.add("");
    for (i = 0; i < d.size();)
        d.set(i, b + d.get(i++));
    return d;
}

Ich werde morgen eine Erklärung hinzufügen.


0

Python, 212 Zeichen

def p(t,f="",o="",d=0):
 if[]==t:return
 b=[""]
 for c in t:d+=c=="[";b[-1]+=c;d-=c=="]";b+=[""]*(d==0)*(c=="]")
 for r in b[:-1]:i=r.index("[");w,s=f+r[:i],r[i:][1:-1];p(s,w);o+= ["",w+"\n"][""==s]
  if o:print o,

Ich hatte gehofft, unter 200 zu werden, aber trotzdem bin ich ziemlich zufrieden damit.


0

Javascript ES6, 142 Bytes

s=>(o=[],x=_=>s[0]==']'?s=s.slice(1):0,(g=d=>{while(s&&!x())[o[d],s]=s.split(/\[(.*)/).concat``,x()?console.log(o.join``):g(d+1),o.pop()})(0))

0

F: 70 Bytes

f:{,/'$({(z_x),y}\[();{`$x@&~x="]"}'w;-b])@-1+&0<b:(+/"]"=)'w:"["\:x}

definiert eine Funktion f, die eine Zeichenfolge akzeptiert und eine Liste von Zeichenfolgen (Wörtern) zurückgibt

Als Lambda (anonyme Funktion) löschen wir die ersten 2 Zeichen f :, die Länge beträgt also 68 Bytes

Prüfung

f "cat[s[up[][]][]ch[e[r[]s[]]]a[maran[]comb[]pult[[]ing[]]]]"

("catsup"; "cats"; "cat"; "catcher"; "catches"; "catamaran"; "catacomb"; "catapult"; "catapulting")

f "[donut[][]cruller[]]"

("donut"; ""; "cruller")

f "[[[[[]]]]]"

""

Anmerkungen

"" gibt eine Liste von Zeichenfolgen an, die nur eine leere Zeichenfolge enthält

Symbole sind atomar. Das Drücken / Aufsetzen eines Symbols auf dem Stapel ist eine einfache Operation, die nicht von der Länge des Symbols abhängt (siehe Erläuterung).

Erläuterung

Q ist ein Cousin von APL (kx.com)

Pseudocode:

  • Teilt den String (arg x) um "[" Zeichen. Ergebnis (Liste der Zeichenketten) in w
  • Zählt "]" Zeichen in jedem Element. von w. Ergebnis in b
  • Ändert jedes Element in w, um das Zeichen "]" herauszufiltern, und konvertiert jede Zeichenfolge in ein Symbol
  • Erzeugt eine logische Sequenz (Bitmap), um Elemente> 0 in b zu markieren
  • Iteriert über Teilergebnisse mit einem Stapel: Wenn ein Element markiert ist, müssen wir eines oder mehrere Symbole löschen (entsprechend dem Wert in b). Hänge immer das aktuelle Symbol an den Stapel an
  • Nach dem Iterieren haben wir alle Zwischenzustände des Stapels. Wir wählen vorher markierte Staaten aus
  • Schließlich konvertieren wir für jedes Ergebnis Symbole in Zeichenfolgen und verketten sie

-1

Cobra - 181

def f(s='')as String*
    for m in RegularExpressions.Regex.matches(s,r'(\w*)\[((?:(?<B>\[)|\w|(?<-B>]))*)](?(B)(?!))'),for r in.f('[(u=m.groups)[2]]'),yield'[u[1]]'+r
    if''==s,yield''

Wenn der Downvoter einen Kommentar hinterlassen würde, der besagt, was daran falsch ist, wäre das zu begrüßen.
Οurous
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.