Drzewa binarne w OCAMLu



Widzisz wersję archiwalną tematu "Drzewa binarne w OCAMLu" z forum pl.comp.programming





red - 26 Mar 2005, 10:05

Witam.

Nie wiem czy ktos tu zajmuje sie tak wymyslnym jezykiem jak OCAML (albo
w ogole czyms funkcyjnym), ale zaryzykuje.

Polimorficzne drzewa binarne są zdefiniowane następująco:
type 'a binTree = Node of 'a binTree * 'a * 'a binTree | Empty;;

Napisz funkcję getSubTrees: 'a binTree -int -('a binTree) list ,
która dla zadanego drzewa binarnego zwróci listę wszystkich poddrzew o
wysokości x.

Moim problemem nie jest nieumiejetnosc wklepania tego czy wymyslenia
algorytmu, lecz po prostu nie rozumiem tresci zadania, nie wiem co mam
otrzymac?!
Jesli ktos umie wyklepac ta funkcyjke to bylbym wdzieczny, a jesli nie
to chociaz jakies propozycje co powinienem otrzymac gdy dla takiego drzewa:

let tt = Node (Node (Empty, 1, Empty), 2, Node (Empty, 3, Node (Empty,
4, Empty)));;

Wywolam funkcje na takie 2 sposoby:
getSubTrees tt 1;;   i   getSubTrees tt 2;;

Dzieki. I przy okazji wesolych Swiat Wielkanocnych, duzo zdrowia przede
wszystkim, bo ja wlasnie sie rozchorowalem :/



Maciek Kalbarczyk - 27 Mar 2005, 09:21

Witam.

Polimorficzne drzewa binarne są zdefiniowane następująco:
type 'a binTree = Node of 'a binTree * 'a * 'a binTree | Empty;;



Czyli każde (pod)drzewo (pod)drzewa elementów typu 'a (dowolnego) jest
albo jest liściem (Empty) albo jest trójką postaci
drzewo elementów typu 'a, element typu 'a, drzewo elementów typu 'a.

Napisz funkcję getSubTrees: 'a binTree -int -('a binTree) list ,
która dla zadanego drzewa binarnego zwróci listę wszystkich poddrzew o
wysokości x.

Moim problemem nie jest nieumiejetnosc wklepania tego czy wymyslenia
algorytmu, lecz po prostu nie rozumiem tresci zadania, nie wiem co mam
otrzymac?!
Jesli ktos umie wyklepac ta funkcyjke to bylbym wdzieczny, a jesli nie
to chociaz jakies propozycje co powinienem otrzymac gdy dla takiego



drzewa:

Masz dostać funkcję postaci:

getSubTrees: 'a binTree -int -'a binTree list

Elementami ostatecznej listy mają być drzewa. Każde z tych drzew ma być
poddrzewem drzewa wyjściowego. Każde z tych drzew ma mieć wysokość
równą drugiemu argumentowi. Zauważ, że mówiąc drzewo mamy na myśli
w tym przypadku albo Liść (Empty) albo trójkę postaci
(lewe poddrzewo, wartość, prawe poddrzewo).

Funkcja, która zwróci listę wszystkich poddrzew może wyglądać na przykład
tak (nie sprawdzałem czy działa).

let wszystkie drzewo =
    let rec pom drzewo lista = match drzewo with
    | Empty -Empty::lista
    | Node of (lewe,_,prawe) as korzen -
        korzen::(wszystkie lewe)::(wszystkie prawe)::lista
in pom drzewo [] ;;

pozdrawiam
Maciek


Maciek Kalbarczyk - 27 Mar 2005, 09:25

let wszystkie drzewo =
    let rec pom drzewo lista = match drzewo with
    | Empty -Empty::lista
    | Node of (lewe,_,prawe) as korzen -
        korzen::(wszystkie lewe)::(wszystkie prawe)::lista
in pom drzewo [] ;;



Powinno byc

    | Node of (lewe,_,prawe) as korzen -
     korzen::(wszystkie lewe lista)::(wszystkie prawe lista)::lista

pozdrawiam, WŚ!
Maciek


red - 28 Mar 2005, 16:07


| let wszystkie drzewo =
|    let rec pom drzewo lista = match drzewo with
|    | Empty -Empty::lista
|    | Node of (lewe,_,prawe) as korzen -
|        korzen::(wszystkie lewe)::(wszystkie prawe)::lista
| in pom drzewo [] ;;

Powinno byc

    | Node of (lewe,_,prawe) as korzen -
     korzen::(wszystkie lewe lista)::(wszystkie prawe lista)::lista



Dzieki za odzew. Poprawilem troche Twoj kod, bo chyba pisales tak z
glowy nie sprawdzajac :) Niestety nadal z zadaniem sie nie uporalem -
przynajmniej rozumiem o co w nim chodzi, ale...

Doszedlem do takiego kodu:

let wszystkie t =
     let rec pom = function
     | (Empty, lista) -Empty :: lista
     | (Node(l, w, p), lista) -
          Node(l, w, p) :: pom (l, lista) :: pom (p, lista) :: lista
   in pom (t, []);;

Wydawac by sie moglo, ze wszystko jest w porzadku, a ocaml rzuca takim
bledem:

Characters 133-147:
       | (Node(l, w, p), lista) -Node(l, w, p) :: pom (l, lista) ::
pom (p, lista) :: lista
                                                    ^^^^^^^^^^^^^^
This expression has type 'a binTree list but is here used with type
   'a binTree

Nie bardzo rozumiem dlaczego, poniewaz podkreslone "pom (l, lista)"
zwraca faktycznie liste, a operator "::" jednak sie czepia :(

Co jak co, z ocamlem zawsze mialem problemy, ale tym razem juz po prostu
rece mi opadaja :/



Marcin 'Qrczak' Kowalczyk - 28 Mar 2005, 16:55


          Node(l, w, p) :: pom (l, lista) :: pom (p, lista) :: lista
   in pom (t, []);;



Operator :: dokłada jeden element na początek listy, jego typ to
   'a -'a list -'a list

Sklejanie dwóch list ma kosz O(długość_lewej). Żeby całość była
efektywniejsza, można by przekazywać "akumulator", do którego zostanie

można pominąć...


red - 28 Mar 2005, 17:30


Operator :: dokłada jeden element na początek listy, jego typ to
   'a -'a list -'a list




raczej, ze nie potrafie poradzic sobie w tym konkretnym przypadku. Nie
wiem dlaczego :/

Sklejanie dwóch list ma kosz O(długość_lewej). Żeby całość była
efektywniejsza, można by przekazywać "akumulator", do którego zostanie

można pominąć...



O rekursji ogonowej tez wiem :)


Marcin 'Qrczak' Kowalczyk - 29 Mar 2005, 04:30



raczej, ze nie potrafie poradzic sobie w tym konkretnym przypadku.
Nie wiem dlaczego :/



Node(l, w, p) jest jednym węzłem, pom zwraca listę węzłów, więc zamiast
   Node(l, w, p) :: pom (l, lista) :: pom (p, lista) :: lista
powinno być

| Sklejanie dwóch list ma kosz O(długość_lewej). Żeby całość była
| efektywniejsza, można by przekazywać "akumulator", do którego zostanie

| można pominąć...

O rekursji ogonowej tez wiem :)




przebiegającego kopie tej samej listy.

Sztuczka polega na tym, że funkcja - zamiast zwracać listę - dokleja
ją na początek dodatkowego parametru. Dzięku temu jeśli rekurencyjne
wywołanie chce dokleić coś z prawej strony wyniku, to zamiast

listę do doklejenia jako dodatkowy parametr.


red - 29 Mar 2005, 14:39


Node(l, w, p) jest jednym węzłem, pom zwraca listę węzłów, więc zamiast
   Node(l, w, p) :: pom (l, lista) :: pom (p, lista) :: lista
powinno być



Racja, dzieki. Nie wiem czasami, mam takie zacmienie, ze najprostsze
rzeczy staja sie trudne.

Zadanie ostatecznie udalo mi sie rozwiazac i w celach edukacyjnych
wklejam tutaj tresc (moze sie komus przyda). Nie jest to zapewne
najoptymalniesze rozwiazanie, ale dziala poprawnie.

let rec wys (t, acc) =
   match t with
   | Empty -acc-1
   | Node(l, v, r) -
     let wl = wys(l, acc+1) and wr = wys(r, acc+1) in
     if wl wr then wl else wr;;

let getSubTrees t n =
     let rec get (t, n, acc) =
     match t with
     | Empty -acc
     | Node(l, v, r) -
       if wys(t, 0) = n then Node(l, v, r) :: acc

   in get(t, n, []);;

LALR i minus unarny/binarny - kompilator
sotowanie przez wstawianie z wyszukiwaniem binarnym ?
Edytor binarny - jakiś dobry potrzebny
API i HWND Popup
  • mapy geologiczne polski
  • mapa ponania
  • fotele samochodowe do busa
  • takkyu ishino mayday
  • fryzury mary j blige
  • biuro podrozy bama
  • cena ziemniakow
  • grand theft auto iv aka gta iv 50
  • portugalia superliga
  • Katalog wypowiedzi z for internetowych ^^ Strona Główna