İkili ağaçlar
İkili ağaç, üç tip düğümü olan bir ağaçtır:
- çocuğu olmayan terminal düğümleri
- her biri bir çocuğu olan tekli düğümler
- her biri iki çocuğu olan ikili düğümler
Bunları BNF'de (Backus-Naur formu) verilen aşağıdaki dilbilgisi ile temsil edebiliriz :
<e> ::=
<terminal>
| <unary>
| <binary>
<terminal> ::=
"0"
<unary> ::=
"(1" <e> ")"
<binary> ::=
"(2" <e> " " <e> ")"
Bu dilbilgisinde düğümler ön siparişte verilir ve her bir düğüm, sahip olduğu çocuk sayısı olan bir rakamla temsil edilir.
Motzkin numaraları
Motzkin numaralar ( OEIS ) ( Vikipedi ) bir çok yorumlar var, ama bir yorumlama olmasıdır n
Motzkin numarası inci ile ayrı ikili ağaçların sayısıdır n
düğümler. Motzkin sayıları tablosu başlar
N Motzkin number M(N)
1 1
2 1
3 2
4 4
5 9
6 21
7 51
8 127
...
örneğin M(5)
9'dur ve 5 düğümü olan dokuz ayrı ikili ağaç
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)
Görev
n
Giriş olarak tek bir pozitif tamsayı alın ve n
düğümlerle birlikte tüm ikili ağaçların çıktısını alın .
n
Okunabilirlik için parantez içeren 1'den 5'e kadar örnekler
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)
Giriş
Giriş bir pozitif tamsayı olacaktır.
Çıktı
Çıktı, bu çok sayıda düğümle ayrı ikili ağaçların anlaşılır bir temsili olmalıdır. Yukarıdaki BNF dilbilgisi tarafından verilen dizgenin tam olarak kullanılması zorunlu değildir: kullanılan sözdiziminin ağaçların açık bir temsilini vermesi yeterlidir. Örneğin Kullanabileceğin []
yerine ()
parantez ekstra düzeyi [[]]
yerine []
, dış parantez vb ekstra virgül veya hiç virgül, fazladan boşluk, parantez veya hiç parantez, mevcut veya eksik
Bunların hepsi eşdeğerdir:
(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
Ayrıca bir yorumda @xnor tarafından amaçlanan bir varyasyon. Bunu anlaşılabilecek bir formata çevirmenin bir yolu olduğundan kabul edilebilir.
[[[]][]] is (2 (1 0) 0)
Kolay bu bazılarını dönüştürmek anlamalarını sağlamak []
için ()
bu yüzden mi
[([])()]
Şimdi ile başlarsanız
[]
sonra iki ifadeye ihtiyaç duyan bir ikili kod ekleyin
[()()] which is 2
ve sonra ilk () için bir ifadeye ihtiyaç duyan bir tekli
[([])()] which is 21
ancak iç parantez içermeyen []
veya ()
içermeyen, daha fazla ifade gerektirmeyen 0'ı temsil edebildiğinden, bunu şu şekilde yorumlayabilirsiniz:
2100
Yanıtların teorik olarak sonsuz bellekle çalışması gerektiğini, ancak uygulamaya bağlı sonlu giriş için bellekte yer kalmayacağını unutmayın.
Çıktı varyasyonları
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)
Yinelenen ağaçları kontrol etmek için olası bir yer
Kopyaları kontrol etmek için bir yer M (5) 'dir.
Bu bir ağaç M (4) ağaçlarından M (5) için iki kez üretildi
(2 (1 0) (1 0))
ilki bir tekli dal ekleyerek
(2 (1 0) 0)
ve ikincisi,
(2 0 (1 0))
BNF'yi anlama
BNF basit kurallardan oluşur:
<symbol> ::= expression
solda etrafı çevrili bir sembol adıdır <>
.
Sağda, sembolü oluşturmak için kullanılan ifade bulunur. Bazı kurallar yapıdaki diğer kuralları kullanır, örn.
<e> ::= <terminal>
e
Olabilir terminal
ve bazı kurallarda sembolün oluşturulmasında kullanılan karakterler vardır, ör.
<terminal> ::= "0"
terminal
sadece sıfır karakteri.
Bazı kuralların bunları yapılandırmanın birden fazla yolu vardır, ör.
<e> ::=
<terminal>
| <unary>
| <binary>
A e
, a <terminal>
veya a <unary>
veya a olabilir <binary>
.
Ve bazı kurallar bir parça dizisidir, ör.
<unary> ::= "(1" <e> ")"
Bir unary
karakterdir (1
için inşa edilebilir ne izledi e
izledi )
.
Bunun için her zaman başlangıç kuralıyla başlarsınız <e>
.
Bazı basit örnekler:
En basit sekans sadece 0
. Bu yüzden başlangıç kuralıyla başlıyoruz <e>
ve üç seçenek olduğunu görüyoruz:
<terminal>
| <unary>
| <binary>
ilkini al <terminal>
. Artık bir terminalin seçeneği yok ve öyle 0
. Yani yerini <terminal>
ile 0
de <e>
kural ve bitirdiniz.
Sonra bir sonraki (1 0)
. İle başlayın <e>
ve kullanım kuralı <unary>
vardır
"(1" <e> ")"
Şimdi bunun bir ihtiyacı var, <e>
bu yüzden geri dönüyoruz <e>
ve bu sefer seçen üç taneden birini <terminal>
seçiyoruz 0
. Değiştirme 0
içine (1 <e> )
verir (1 0)
ve içine bu değiştirilir <unary>
böylece <e>
olduğunu (1 0)
.