접두사 트리 탐색


13

재귀 형식의 문자열을 stdin 또는 명령 줄을 통해 사용하는 프로그램을 작성하십시오.

PREFIX[SUFFIXES]

어디

  • PREFIX 빈 문자열을 포함하여 소문자 문자열 (az) 일 수 있습니다.
  • SUFFIXESPREFIX[SUFFIXES]빈 시퀀스를 포함하여 재귀 형식이 함께 연결된 문자열 시퀀스 일 수 있습니다 .

각 접미사에서 문자열 목록을 재귀 적으로 평가하고 접두사에 추가하여 입력에서 소문자 문자열 목록을 생성하십시오. 이 목록의 문자열을 한 줄에 하나씩 순서대로 stdout하기위한 출력 (선택적 후행 줄 바꿈)

입력이

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

하스켈, 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 "[[[[[]]]]]"
[""]

코드는 125가 아니라 124 바이트입니다.
Cristian Lupascu

나는 패턴이 생각 (a,(_:t))할 수 있습니다 (a,_:t)대신
자랑 haskeller

2

자바, 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

자바 스크립트 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를 정의합니다.

람다 (익명 함수)로서 우리는 처음 두 문자 f를 삭제합니다 : 그래서 길이는 68 바이트입니다

테스트

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

( "도넛"; ""; "크롤러")

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

""

노트

, ""는 빈 문자열 만 포함하는 문자열 목록을 나타냅니다.

기호는 원자 적입니다. 스택의 심볼 푸시 / 팝은 심볼의 길이에 영향을받지 않는 간단한 조작입니다 (설명 참조).

설명

Q는 APL (kx.com)의 사촌입니다

의사 코드 :

  • "["char에서 문자열 (arg x)을 분할합니다. w의 결과 (문자열 목록)
  • 각 요소에서 "]"문자를 셉니다. w. b 결과
  • 문자 "]"를 걸러 내도록 w의 각 항목을 수정하고 각 문자열을 기호로 변환
  • b에서 항목> 0을 표시하기 위해 논리 시퀀스 (비트 맵)를 생성합니다.
  • 스택으로 부분 결과를 반복합니다. 항목이 표시되면 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가 이것에 어떤 문제가 있는지에 대한 의견을 남기면 감사하겠습니다.
OUurous
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.