ต้นไม้ไบนารี
ต้นไม้ไบนารีเป็นต้นไม้ที่มีโหนดสามประเภท:
- โหนดเทอร์มินัลซึ่งไม่มีลูก
- โหนดเดียวซึ่งมีลูกหนึ่งคน
- โหนดฐานสองซึ่งมีลูกสองคน
เราสามารถเป็นตัวแทนของพวกเขาด้วยไวยากรณ์ต่อไปนี้ที่กำหนดในBNF (รูปแบบ Backus – Naur):
<e> ::=
<terminal>
| <unary>
| <binary>
<terminal> ::=
"0"
<unary> ::=
"(1" <e> ")"
<binary> ::=
"(2" <e> " " <e> ")"
ในไวยากรณ์นี้โหนดจะได้รับในการสั่งซื้อล่วงหน้าและแต่ละโหนดจะมีตัวเลขซึ่งเป็นจำนวนของเด็กที่มี
ตัวเลข Motzkin
หมายเลข Motzkin ( OEIS ) ( Wikipedia ) มีการตีความหลายอย่าง แต่หนึ่งการตีความคือn
หมายเลข Motzkin ที่สามคือจำนวนของต้นไม้ไบนารีที่แตกต่างกับn
โหนด ตารางหมายเลข Motzkin เริ่มต้นขึ้น
N Motzkin number M(N)
1 1
2 1
3 2
4 4
5 9
6 21
7 51
8 127
...
เช่นM(5)
เป็น 9 และต้นไม้ไบนารีที่แตกต่างกันเก้ากับ 5 โหนดคือ
1 (1 (1 (1 (1 0))))
2 (1 (1 (2 0 0)))
3 (1 (2 0 (1 0)))
4 (1 (2 (1 0) 0))
5 (2 0 (1 (1 0)))
6 (2 0 (2 0 0))
7 (2 (1 0) (1 0))
8 (2 (1 (1 0)) 0)
9 (2 (2 0 0) 0)
งาน
ใช้จำนวนเต็มบวกเดียวn
เป็นอินพุตและเอาต์พุตต้นไม้ไบนารีที่แตกต่างกันพร้อมn
โหนด
ตัวอย่างn
จาก 1 ถึง 5 ที่มีวงเล็บรวมอยู่เพื่อให้สามารถอ่านได้
0
(1 0)
(1 (1 0))
(2 0 0)
(1 (1 (1 0)))
(1 (2 0 0))
(2 0 (1 0))
(2 (1 0) 0)
(1 (1 (1 (1 0))))
(1 (1 (2 0 0)))
(1 (2 0 (1 0)))
(1 (2 (1 0) 0))
(2 0 (1 (1 0)))
(2 0 (2 0 0))
(2 (1 0) (1 0))
(2 (1 (1 0)) 0)
(2 (2 0 0) 0)
อินพุต
อินพุตจะเป็นจำนวนเต็มบวกหนึ่งตัว
เอาท์พุต
เอาท์พุทควรจะเป็นตัวแทนที่เข้าใจได้ของต้นไม้ไบนารีที่แตกต่างกับหลายโหนด ไม่จำเป็นต้องใช้สตริงที่แน่นอนที่กำหนดโดยไวยากรณ์ BNF ด้านบน: มันเพียงพอแล้วที่ไวยากรณ์ที่ใช้จะให้การแสดงต้นไม้อย่างชัดเจน เช่นคุณสามารถใช้[]
แทน()
วงเล็บระดับพิเศษ[[]]
แทน[]
วงเล็บด้านนอกมีอยู่หรือขาดหายไปเครื่องหมายจุลภาคพิเศษหรือไม่มีเครื่องหมายจุลภาคช่องว่างพิเศษวงเล็บหรือไม่มีวงเล็บเป็นต้น
ทั้งหมดนี้เทียบเท่า:
(1 (2 (1 0) 0))
[1 [2 [1 0] 0]]
1 2 1 0 0
12100
(1 [2 (1 0) 0])
.:.--
*%*55
(- (+ (- 1) 1))
-+-11
นอกจากนี้รูปแบบที่ระบุโดย @xnor ในความคิดเห็น เนื่องจากมีวิธีการแปลเป็นรูปแบบที่สามารถเข้าใจได้จึงเป็นที่ยอมรับ
[[[]][]] is (2 (1 0) 0)
เพื่อให้ง่ายต่อการเข้าใจการแปลงบางสิ่งที่[]
เป็น()
เช่นนั้น
[([])()]
ตอนนี้ถ้าคุณเริ่มต้นด้วย
[]
จากนั้นใส่ไบนารี่ซึ่งต้องการสองนิพจน์ที่คุณได้รับ
[()()] which is 2
และสำหรับอันแรก () แทรกยูนารีซึ่งต้องการนิพจน์เดียวที่คุณได้รับ
[([])()] which is 21
แต่เนื่องจาก[]
หรือ()
ไม่มีการถ่ายคร่อมด้านในสามารถเป็นตัวแทน 0 ซึ่งไม่ต้องการนิพจน์อีกต่อไปคุณจึงสามารถตีความได้ว่า
2100
โปรดทราบว่าคำตอบควรทำงานได้ในทางทฤษฎีกับหน่วยความจำที่ไม่มีที่สิ้นสุด แต่จะเห็นได้ว่าหน่วยความจำไม่เพียงพอสำหรับอินพุต จำกัด ที่ขึ้นอยู่กับการใช้งาน
รูปแบบของการส่งออก
BNF xnor Christian Ben
b(t, b(t, t)) [{}{{}{}}] (0(00)) (1, -1, 1, -1)
b(t, u(u(t))) [{}{(())}] (0((0))) (1, -1, 0, 0)
b(u(t), u(t)) [{()}{()}] ((0)(0)) (1, 0, -1, 0)
b(b(t, t), t) [{{}{}}{}] ((00)0) (1, 1, -1, -1)
b(u(u(t)), t) [{(())}{}] (((0))0) (1, 0, 0, -1)
u(b(t, u(t))) [({}{()})] ((0(0))) (0, 1, -1, 0)
u(b(u(t), t)) [({()}{})] (((0)0)) (0, 1, 0, -1)
u(u(b(t, t))) [(({}{}))] (((00))) (0, 0, 1, -1)
u(u(u(u(t)))) [(((())))] ((((0)))) (0, 0, 0, 0)
สถานที่ที่เป็นไปได้ในการตรวจสอบต้นไม้ที่ซ้ำกัน
ที่เดียวที่จะตรวจสอบความซ้ำซ้อนคือด้วย M (5)
ต้นไม้หนึ่งต้นนี้ถูกสร้างขึ้นสองครั้งสำหรับ M (5) จากต้นไม้ M (4)
(2 (1 0) (1 0))
เป็นครั้งแรกโดยการเพิ่มสาขาเอกเพื่อ
(2 (1 0) 0)
และที่สองโดยเพิ่มสาขาเอก
(2 0 (1 0))
ทำความเข้าใจกับ BNF
BNF ประกอบด้วยกฎง่าย ๆ :
<symbol> ::= expression
<>
ที่ด้านซ้ายเป็นชื่อสัญลักษณ์ที่ล้อมรอบด้วย
ด้านขวาเป็นนิพจน์สำหรับสร้างสัญลักษณ์ กฎบางข้อใช้กฎอื่น ๆ ในการก่อสร้างเช่น
<e> ::= <terminal>
e
สามารถเป็น terminal
และกฎบางอย่างมีอักขระที่ใช้ในการสร้างสัญลักษณ์เช่น
<terminal> ::= "0"
terminal
เป็นเพียงตัวละครที่เป็นศูนย์
กฎบางข้อมีหลายวิธีในการสร้างกฎเช่น
<e> ::=
<terminal>
| <unary>
| <binary>
e
สามารถเป็น<terminal>
หรือหรือ<unary>
<binary>
และบางกฎก็เป็นลำดับของชิ้นส่วนเช่น
<unary> ::= "(1" <e> ")"
unary
เป็นตัวละคร(1
ตามมาด้วยสิ่งที่สามารถสร้างขึ้นสำหรับการตามe
)
<e>
คุณมักจะเริ่มต้นด้วยกฎเริ่มต้นซึ่งสำหรับเรื่องนี้
ตัวอย่างง่ายๆ:
0
ลำดับที่ง่ายที่สุดคือเพียง ดังนั้นเราเริ่มต้นด้วยกฎเริ่มต้น<e>
และดูว่ามีสามตัวเลือก:
<terminal>
| <unary>
| <binary>
<terminal>
เพื่อใช้เป็นคนแรก 0
ตอนนี้เทอร์ไม่มีทางเลือกและมี ดังนั้นแทนที่<terminal>
ด้วย0
ใน<e>
กฎและคุณเสร็จแล้ว
(1 0)
จากนั้นหนึ่งต่อไปคือ เริ่มต้นด้วย<e>
และใช้กฎ<unary>
ที่มี
"(1" <e> ")"
ตอนนี้ความต้องการ<e>
เพื่อให้เรากลับไป<e>
และให้ทางเลือกของหนึ่งในสามคราวนี้การเลือกซึ่งจะช่วยให้<terminal>
0
ใส่0
เข้าไป(1 <e> )
ให้(1 0)
และนี้จะถูกแทนที่ลงไป<unary>
เพื่อให้เป็น<e>
(1 0)