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


13

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

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

Описание

Программа получает ввод из стандартного ввода и выводит результат в стандартный вывод.

Он проходит по дереву, сохраняя текущую ветку в стеке. Там также другой стек, называемый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;}
}

Expanded:

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

( «Кетчуп», «кошки», «кошки», «зрелище», «ловит», «катамаран», «катакомбы», «катапульта», «выстреливает»)

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

( "Бублик"; ""; "Cruller")

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

, ""

Примечания

, "" указывает на список строк, который содержит только пустую строку

Символы атомарные. Выдвинуть / сложить символ в стеке - это простая операция, на которую не влияет длина символа (см. Пояснение).

объяснение

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''

Если бы downvoter оставил комментарий, говорящий, что случилось с этим, это было бы оценено.
'35
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.