Tìm nút sâu nhất của cây nhị phân


9

Viết chương trình lấy cây nhị phân làm đầu vào và xuất ra nút sâu nhất và độ sâu của nó. Nếu có một cà vạt, in tất cả các nút liên quan cũng như độ sâu của chúng. Mỗi nút được biểu diễn dưới dạng:

T(x,x)

T(x)

T

trong đó Tđịnh danh của một hoặc nhiều ký tự chữ và số và mỗi ký tự xlà một nút khác.

Đây là một định nghĩa đơn giản về cây nhị phân:

  • Ở đầu cây nhị phân là một nút.
  • Một nút trong cây nhị phân có nhiều nhất hai con.

Ví dụ, đầu vào A(B(C,D(E)))(bên dưới) sẽ xuất ra 3:E.

Cây 1

Trong khi cây sau đây là một liên kết ba chiều giữa 5, 11 và 4 và độ sâu của chúng cũng là 3 (bắt đầu từ 0):

Đầu vào 2(7(2,6(5,11)),5(9(4)))(bên dưới) sẽ xuất ra 3:5,11,4.

Cây 2

Đây là mã golf, vì vậy mã ngắn nhất được đo bằng byte sẽ thắng.


@ cử tri thân thiết: bạn không rõ về điều gì?
Jwosty

3
Có lẽ thực tế là không có đặc điểm kỹ thuật đầu vào hoặc đầu ra, hoặc các trường hợp thử nghiệm cho các đầu vào và đầu ra đó.
Doorknob

Cố gắng sửa nó nhưng điện thoại của tôi thật tệ ... Mặc dù vậy nó vẫn tốt hơn.
Jwosty

3
Không phải cây đầu tiên là A (B (C, D (E))?
bakerg

1
@bakerg đúng rồi, lỗi của tôi. Đã sửa.
Jwosty

Câu trả lời:


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

Tôi đã thực hiện một sửa đổi nhỏ cho định dạng đầu ra để làm cho nó nhất quán và ít mơ hồ hơn, nhưng nó không quá bất tiện.
Jwosty

@Jwosty Không nên, nếu đây không phải là môn đánh gôn.
jimmy23013

Chà, đây môn đánh gôn ... Nhưng dù sao đi nữa, bài nộp hay :)
Jwosty

Bạn có thể vui lòng giải thích làm thế nào điều này hoạt động?
Jerry Jeremiah

@JerryJeremiah Đã chỉnh sửa.
jimmy23013

5

Haskell, 186 byte

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,"")%)

Chương trình đầy đủ, bật cây stdin, tạo định dạng đầu ra cụ thể trên 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

Hướng dẫn về mã golf (đã thêm tên tốt hơn, chữ ký loại, nhận xét và một số biểu hiện phụ được rút ra và đặt tên - nhưng nếu không thì cùng một mã; phiên bản không được phép sẽ không thể xâm nhập vào các nút bằng cách đánh số, cũng không tìm thấy sâu nhất với định dạng đầu ra.) :

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
Mã đó làm tôi kinh hoàng.
xem

Mã giải thích mở rộng được thêm vào! Hãy để nỗi kinh hoàng làm cho bạn mạnh mẽ hơn !!
MtnViewMark

Bạn xứng đáng được +1 cho điều đó.
xem

Ôi chúa ơi, và tôi đang vật lộn với danh sách: P
Artur Trapp

4

GolfScript (75 ký tự)

Không đặc biệt cạnh tranh, nhưng đủ xoắn mà nó có một số lợi ích:

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

Mã có ba giai đoạn. Đầu tiên, chúng tôi xử lý chuỗi đầu vào:

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

Chúng tôi đã chuyển ví dụ như A(B(C,D(E)))để 'A'^('B'^('C'^'D'^('E'^)''^)''^). Nếu chúng ta gán một khối phù hợp cho ^chúng ta có thể xử lý hữu ích bằng cách sử dụng ~để đánh giá chuỗi.

Thứ hai, chúng tôi tìm thấy độ sâu tối đa:

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~

Cuối cùng, chúng tôi chọn các nút sâu nhất và xây dựng đầu ra:

# 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

Perl 5 - 85

Xin vui lòng chỉnh sửa bài đăng này để sửa số lượng nhân vật. Tôi sử dụng saytính năng, nhưng tôi không biết về các cờ để làm cho nó chạy chính xác mà không cần khai báo use 5.010;.

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

Bản demo trên ideone

Đầu ra được phân tách bằng dấu cách thay vì phân tách bằng dấu phẩy.

Mã chỉ đơn giản là sử dụng regex đệ quy để loại bỏ gốc của cây trong rừng, cho đến khi không thể làm như vậy. Sau đó, chuỗi trước cuối cùng sẽ chứa tất cả các nút lá ở mức sâu nhất.

Chạy mẫu

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

Giả định: Node giá trị không thể chứa ,, (,)


1
Điều này dường như không được chơi golf ở tất cả. Bạn không thể xóa hầu hết khoảng trắng đó (tôi không biết VB)?
xem

Phụ thuộc một số khoảng trắng là đáng kể.
Adam Speight

1

Javascript (E6) 120

Phiên bản lặp

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

Ung dung và thử nghiệ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]
)

Kiểm tra trong bảng điều khiển Firefox:

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

Đầu ra

"A -> 0: A

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

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

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.