Префікс обходу дерева


13

Напишіть програму, яка містить (через stdin чи командний рядок) рядок із рекурсивною формою

PREFIX[SUFFIXES]

де

  • PREFIX може бути будь-який рядок малих літер (az), включаючи порожній рядок, і
  • SUFFIXESможе бути будь-яка послідовність рядків з рекурсивною формою, PREFIX[SUFFIXES]з'єднаною разом, включаючи порожню послідовність.

Створіть із вхідного списку рядки з літери з малих літер, рекурсивно оцінивши список рядків у кожному із суфіксів та додавши їх до префікса. Виведіть для викреснення рядків у цьому списку в будь-якому порядку, по одному на рядок (плюс необов'язковий кінцевий новий рядок).

Приклад

Якщо вхід є

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

то префікс catі і суфікси s[up[][]], [], ch[e[r[]s[]]], і a[maran[]comb[]pult[[]ing[]]]. Кожен суфікс по черзі має свій префікс і суфікси.

Результатом буде ці 9 слів у будь-якому порядку

catsup
cats
cat
catcher
catches
catamaran
catacomb
catapult
catapulting

тому що вхід кодує це дерево

схема дерева

і кожне з 9 вихідних слів може бути утворене шляхом обходу дерева від кореня до листа.

Примітки

  • Пам'ятайте, що префікс може бути порожнім рядком, тому щось подібне

    [donut[][]cruller[]]
    

    допустимий вхід, вихід якого буде (у будь-якому порядку)

    donut
    
    cruller
    

    де порожній рядок - порожній рядок, який відповідає другому суфіксу.

  • Послідовність суфікса також може бути порожньою, тому тривіальний вхідний випадок

    []
    

    як вихід є один порожній рядок:

    
    
  • Ви можете припустити, що введення видасть лише унікальні слова виводу.
    • наприклад hat[s[]ter[]s[]], буде недійсним введення, оскільки hatsкодується двічі.
    • Так само [[][]]недійсний, оскільки порожній рядок кодується двічі.
  • Ви можете не припускати, що вхід є максимально коротким або стислим.
    • наприклад, 'e'вузол у головному прикладі вище може поєднуватися з 'ch'вузлом, але це не означає, що введення недійсне.
    • Аналогічно, [[[[[]]]]]є дійсним, незважаючи лише на кодування порожнього рядка на неоптимальний спосіб.
  • Замість програми ви можете написати функцію, яка приймає рядок введення як аргумент і друкує вихідний звичайно або повертає його як рядок або список.

Виграє найкоротший код у байтах.

Відповіді:


2

Рубі, 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}

Приклад

Спробуйте: http://ideone.com/NW0CNB

Опис

Програма отримує вхід від stdin та виводить результат у stdout.

Він обходить дерево, зберігаючи поточну гілку в стеці. Існує також інший стек, weightsякий називається, який відстежує кількість дітей кожного вузла. Це потрібно для того, щоб визначити, чи справді вузол є листочком, чи це мали діти раніше.

Прочитана програма:

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 байт

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

Функція t(для переходу):

λ: 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 "[[[[[]]]]]"
[""]

Ваш код - 124 байти, а не 125 :)
Крістіан Лупаску

Я думаю, що шаблон (a,(_:t))може бути (a,_:t)замість цього
гордий haskeller

2

Java, 206 байт

Визначає функцію, яка приймає рядок як аргумент і повертає список рядків. Для додаткового бонусу він повертає рядки в тому ж порядку, що і питання.

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;}

Приклад використання:

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;}
}

Розширено:

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;
}

Я завтра додам пояснення.


0

Пітон, 212 символів

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,

Я сподівався потрапити під 200 років, але все-таки я дуже задоволений цим.


0

Javascript ES6, 142 байти

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

Q: 70 байт

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

визначає функцію f, яка приймає рядок і повертає список рядків (слів)

Як лямбда (анонімна функція) ми опускаємо перші 2 символи f :, тому довжина становить 68 байт

Тест

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

("catup"; "коти"; "кішка"; "ловця"; "ловить"; "катамаран"; "катакомба"; "катапульта"; "катапультування")

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

("пончик"; ""; "ватажок")

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

, ""

Примітки

, "" вказує на список рядків, який містить лише порожній рядок

Символи атомні. Push / pop символ на стеку - це проста операція, на яку не впливає довжина символу (див. Пояснення)

Пояснення

Q - двоюрідний брат APL (kx.com)

Псевдокод:

  • Розбиває рядок (arg x) на "[" char. Результат (список рядків) у w
  • Підраховує символи "]" у кожному елемі. з ш. Результат у б
  • Модифікує кожен елемент у w для фільтрації символу "]" та перетворює кожен рядок у символ
  • Створює логічну послідовність (растрову карту) для позначення елементів> 0 в b
  • Ітерація над частковими результатами стеком: якщо пункт позначений, ми повинні скинути один із декількох символів (відповідно до значення в b). Завжди додайте фактичний символ до стеку
  • Після ітерації у нас є всі проміжні стани стека. Вибираємо раніше позначені стани
  • нарешті, для кожного результату ми перетворюємо символи в рядки і з'єднуємо їх

-1

Кобра - 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''

Якщо низовик залишить коментар, в якому сказати, що з цим не так, це буде вдячно.
Οurous
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.