이진 트리의 가장 깊은 노드 찾기


9

이진 트리를 입력으로 사용하여 가장 깊은 노드와 그 깊이를 출력하는 프로그램을 작성하십시오. 동점이있는 경우 모든 관련 노드와 깊이를 인쇄하십시오. 각 노드는 다음과 같이 표시됩니다.

T(x,x)

T(x)

T

여기서 T하나 이상의 영숫자 식별자이며 각각 x다른 노드입니다.

이진 트리에 대한 간단한 정의는 다음과 같습니다.

  • 이진 트리의 선두에는 노드가 있습니다.
  • 이진 트리의 노드에는 최대 두 개의 자식이 있습니다.

예를 들어, 입력 A(B(C,D(E)))(아래)은 출력 3:E됩니다.

나무 1

다음 트리는 5, 11 및 4 사이의 3 방향 타이이며 깊이는 3 (0부터 시작)입니다.

입력 2(7(2,6(5,11)),5(9(4)))(아래)이 출력 3:5,11,4됩니다.

나무 2

이것은 코드 골프이므로 바이트 단위로 측정 된 가장 짧은 코드가 이깁니다.


@ close-voter : 당신은 무엇에 대해 확실하지 않습니까?
Jwosty

3
입력 또는 출력 사양이 없거나 해당 입력 및 출력에 대한 테스트 사례가있을 수 있습니다.
Doorknob

그것을 고치려고 노력하지만 내 전화가 짜증납니다 ... : P 그래도 좋습니다.
Jwosty

3
첫 번째 나무는 A (B (C, D (E))가
아니어야

1
@bakerg 맞아, 내 실수. 결정된.
Jwosty

답변:


6

CJam, 49 47

0q')/{'(/):U;,+:TW>{T:W];}*TW={U]',*}*T(}/;W':@

 

0                 " Push 0 ";
q                 " Read the whole input ";
')/               " Split the input by ')' ";
{                 " For each item ";
  '(/             " Split by '(' ";
  )               " Extract the last item of the array ";
  :U;             " Assign the result to U, and discard it ";
  ,               " Get the array length ";
  +               " Add the top two items of the stack, which are the array length and the number initialized to 0 ";
  :T              " Assign the result to T ";
  W>{             " If T>W, while W is always initialized to -1 ";
    T:W];         " Set T to W, and empty the stack ";
  }*
  TW={            " If T==W ";
    U]',*         " Push U and add a ',' between everything in the stack, if there were more than one ";
  }*
  T(              " Push T and decrease by one ";
}/
;                 " Discard the top item, which should be now -1 ";
W                 " Push W ";
':                " Push ':' ";
@                 " Rotate the 3rd item to the top ";

일관성 있고 모호하지 않도록 출력 형식을 약간 수정했지만 너무 불편하지는 않습니다.
Jwosty

@Jwosty 이것이 코드 골프가 아니라면 안됩니다.
jimmy23013 2016 년

음, 이것은 이다 : 코드 골프 ... 어쨌든, 좋은 제출
Jwosty

이것이 어떻게 작동하는지 설명해 주시겠습니까?
Jerry Jeremiah

@JerryJeremiah 편집했습니다.
jimmy23013 2016 년

5

하스켈, 186 바이트

p@(n,s)%(c:z)=maybe((n,s++[c])%z)(\i->p:(n+i,"")%z)$lookup c$zip"),("[-1..1];p%_=[p]
(n,w)&(i,s)|i>n=(i,show i++':':s)|i==n=(n,w++',':s);p&_=p
main=interact$snd.foldl(&)(0,"").((0,"")%)

전체 프로그램은 트리를 stdin사용하여 stdout다음 에 대해 지정된 출력 형식을 생성합니다 .

& echo '2(7(2,6(5,11)),5(9(4)))' | runhaskell 32557-Deepest.hs 
3:5,11,4

& echo 'A(B(C,D(E)))' | runhaskell 32557-Deepest.hs 
3:E

골프의 코드 안내 (더 나은 이름, 형식 서명, 주석 및 일부 하위 표현 추가 및 명명-그러나 그렇지 않으면 동일한 코드, 골프화되지 않은 버전은 번호가 매겨진 노드로 나누거나 가장 깊은 것을 찾는 것과 혼동하지 않습니다) 출력 형식 지정) :

type Label = String         -- the label on a node
type Node = (Int, Label)    -- the depth of a node, and its label

-- | Break a string into nodes, counting the depth as we go
number :: Node -> String -> [Node]
number node@(n, label) (c:cs) =
    maybe addCharToNode startNewNode $ lookup c adjustTable
  where
    addCharToNode = number (n, label ++ [c]) cs
        -- ^ append current character onto label, and keep numbering rest

    startNewNode adjust = node : number (n + adjust, "") cs
        -- ^ return current node, and the number the rest, adjusting the depth

    adjustTable = zip "),(" [-1..1]
        -- ^ map characters that end node labels onto depth adjustments
        -- Equivalent to [ (')',-1), (',',0), ('(',1) ]

number node _ = [node]      -- default case when there is no more input

-- | Accumulate into the set of deepest nodes, building the formatted output
deepest :: (Int, String) -> Node -> (Int, String)
deepest (m, output) (n, label)
    | n > m     = (n, show n ++ ':' : label)    -- n is deeper tham what we have
    | n == m    = (m, output ++ ',' : label)    -- n is as deep, so add on label
deepest best _ = best                           -- otherwise, not as deep

main' :: IO ()
main' = interact $ getOutput . findDeepest . numberNodes
  where
    numberNodes :: String -> [Node]
    numberNodes = number (0, "")

    findDeepest :: [Node] -> (Int, String)
    findDeepest = foldl deepest (0, "")

    getOutput :: (Int, String) -> String
    getOutput = snd

1
그 코드는 나를 무섭게한다.
seequ

확장 된 설명 코드가 추가되었습니다! 공포가 당신을 더 강하게 만들자!
MtnViewMark

이를 위해 +1이 필요합니다.
seequ

오 세상에, 나는 목록으로 고투하고있다 : P
Artur Trapp

4

GolfScript (75 자)

특히 경쟁적이지는 않지만 관심을 가질 정도로 충분히 왜곡되었습니다.

{.48<{"'^"\39}*}%','-)](+0.{;.@.@>-\}:^;@:Z~{2$2$={@@.}*;}:^;Z~\-])':'@','*

이 코드에는 세 단계가 있습니다. 먼저 입력 문자열을 사전 처리합니다.

# In regex terms, this is s/([ -\/])/'^\1'/g
{.48<{"'^"\39}*}%
# Remove all commas
','-
# Rotate the ' which was added after the closing ) to the start
)](+

A(B(C,D(E)))를로 변환 했습니다 'A'^('B'^('C'^'D'^('E'^)''^)''^). 적절한 블록을 할당 하면 문자열을 평가하는 ^데 사용하여 유용한 처리를 수행 할 수 있습니다 ~.

둘째, 최대 깊이를 찾습니다.

0.
# The block we assign to ^ assumes that the stack is
#   max-depth current-depth string
# It discards the string and updates max-depth
{;.@.@>-\}:^;
@:Z~

마지막으로 가장 깊은 노드를 선택하고 출력을 만듭니다.

# The block we assign to ^ assumes that the stack is
#   max-depth current-depth string
# If max-depth == current-depth it pushes the string under them on the stack
# Otherwise it discards the string
{2$2$={@@.}*;}:^;
# Eval
Z~
# The stack now contains
#   value1 ... valuen max-depth 0
# Get a positive value for the depth, collect everything into an array, and pop the depth
\-])
# Final rearranging for the desired output
':'@','*

1

펄 5-85

이 게시물을 수정하여 문자 수를 수정하십시오. 나는 say기능을 사용 하지만 선언하지 않고 올바르게 실행되도록 플래그에 대해 알지 못합니다 use 5.010;.

$_=$t=<>,$i=0;$t=$_,$i++while s/\w+(\((?R)(,(?R))?\))?/$1/g,/\w/;@x=$t=~/\w+/gs;say"$i:@x"

이데온 데모

출력은 쉼표로 구분되지 않고 공백으로 구분됩니다.

이 코드는 재귀 정규식을 사용하여 가능하지 않을 때까지 포리스트의 나무 뿌리를 제거합니다. 그런 다음 마지막 앞의 문자열에는 가장 깊은 수준의 모든 리프 노드가 포함됩니다.

샘플 런

2
0:2

2(3(4(5)),6(7))
3:5

2(7(2,6(5,11)),5(9(4)))
3:5 11 4

1(2(3(4,5),6(7,8)),9(10(11,12),13(14,15)))
3:4 5 7 8 11 12 14 15

1

VB.net

Function FindDeepest(t$) As String
  Dim f As New List(Of String)
  Dim m = 0
  Dim d = 0
  Dim x = ""
  For Each c In t
    Select Case c
      Case ","
        If d = m Then f.Add(x)
        x = ""
      Case "("
        d += 1
        If d > m Then f.Clear() :
        m = d
        x = ""
      Case ")"
        If d = m Then f.Add(x) : x = ""
        d -= 1
      Case Else
        x += c
    End Select
  Next
  Return m & ":" & String.Join(",", f)
End Function

가정 : 노드 값을 포함 할 수 없습니다 ,, (,)


1
이것은 전혀 골프가 아닌 것 같습니다. 공백을 대부분 제거 할 수 없습니까 (VB를 모르는 경우)?
seequ

일부 공백이 중요합니다.
Adam Speight

1

자바 스크립트 (E6) 120

반복 버전

m=d=0,n=[''];
prompt().split(/,|(\(|\))/).map(e=>e&&(e=='('?m<++d&&(n[m=d]=''):e==')'?d--:n[d]+=' '+e));
alert(m+':'+n[m])

풀리고 테스트 가능

F= a=> (
    m=d=0,n=[''],
    a.split(/,|(\(|\))/)
    .map(e=>e && (e=='(' ? m < ++d && (n[m=d]='') : e==')' ? d-- : n[d]+=' '+e)),
    m+':'+n[m]
)

Firefox 콘솔에서 테스트하십시오 .

['A', '2(7(2,6(5,11)),5(9(4)))', 'A(B(C,D(E)))']
.map(x => x + ' --> ' + F(x)).join('\n')

산출

"A-> 0 : A

2 (7 (2,6 (5,11)), 5 (9 (4)))-> 3 : 5 11 4

A (B (C, D (E)))-> 3 : E "

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.