Rozdział 5 REKURENCJA.

Slides:



Advertisements
Podobne prezentacje
Sortowanie przez scalanie
Advertisements

Algorytmy sortowania i porządkowania
Algorytmy sortowania i przeszukiwania
Język C/C++ Funkcje.
Schemat blokowy M START KONIEC
CIĄGI.
Programowanie I Rekurencja.
Języki programowania C++
Techniki konstrukcji algorytmów
PROGRAMOWANIE STRUKTURALNE
Iteracja, indukcja i rekurencja
ALGORYTMY I STRUKTURY DANYCH
Elementarne struktury danych Piotr Prokopowicz
ZLICZANIE cz. II.
Materiały do zajęć z przedmiotu: Narzędzia i języki programowania Programowanie w języku PASCAL Część 7: Procedury i funkcje © Jan Kaczmarek.
Materiały do zajęć z przedmiotu: Narzędzia i języki programowania Programowanie w języku PASCAL Część 8: Wykorzystanie procedur i funkcji © Jan Kaczmarek.
Modularyzacja i struktury danych w C Copyright, 2005 © Jerzy R. Nawrocki Wprowadzenie.
Modularyzacja i struktury danych w C Copyright, 2005 © Jerzy R. Nawrocki Wprowadzenie.
Język C – Część II Copyright, 2004 © Jerzy R. Nawrocki Wprowadzenie do informatyki.
Macierze Maria Guzik.
Model danych oparty na listach
Podstawy programowania PP – WYK3 Wojciech Pieprzyca.
Podstawy programowania PP – LAB4 Wojciech Pieprzyca.
Jak uczę programowania?
Dr Anna Kwiatkowska Instytut Informatyki
Schemat Hornera Mgr inż. Michał Szucki.
Podstawy programowania
POJĘCIE ALGORYTMU Pojęcie algorytmu Etapy rozwiązywania zadań
Podstawy programowania
Rekurencja.
Algorytmy i Struktury Danych Sortowanie
Programowanie strukturalne i obiektowe
Funkcje w Pascalu Przypomnienie wiadomości o procedurach Prowadzący: Anna Kaleta Piotr Chojnacki.
© A. Jędryczkowski – 2006 r. © A. Jędryczkowski – 2006 r.
Przegląd podstawowych algorytmów
Algorytmy i Struktury Danych Typy algorytmów
Microsoft Office Excel
Algorytmy i struktury danych
Algorytmy i struktury danych
Centrum Kształcenia Ustawicznego im. St. Staszica w Koszalinie
Sortowanie tablic jednowymiarowych
Wykład 10 typ zbiorowy rekurencja.
Ułamki Zwykłe.
Algorytmika Iteracje autor: Tadeusz Lachawiec.
Obliczalność czyli co da się policzyć i jak Model obliczeń maszyna licznikowa dr Kamila Barylska.
Metody numeryczne szukanie pierwiastka metodą bisekcji
TEMAT: UŁAMKI ZWYKŁE.
Algorytmy- Wprowadzenie do programowania
WYKŁAD 06 Programowanie dynamiczne Grażyna Mirkowska.
Rekurencja.
Krakowski Piotr, Woliński Radosław, Kowalski Piotr, Machowski Michał.
Haskell. Dopasowanie do wzorca Jest to operacja, gdzie pewnie wyrażenie sprawdza się ze wzorcem, w którym może znajdować się jedno lub więcej "wolnych.
Funkcje - rekurencja Zajęcia 8. Funkcje - definicja Ogólna postać funkcji w C++: typZwracany nazwaFunkcji(listaParametrówWejściowychFunkcji) { ciało funkcji.
METODY REPREZENTOWANIA IFORMACJI
Instrukcje warunkowe w php. Pętla FOR Czasem zachodzi potrzeba wykonania jakiejś czynności określoną ilość razy. Z pomocą przychodzi jedna z najczęściej.
Temat 3: Podstawy programowania Algorytmy – 2 z 2 _________________________________________________________________________________________________________________.
RODZAJE ALGORYTMÓW 2.-warunkowe 1.-liniowe i=i+1 3.-iteracyjne.
Programowanie I Rekurencja.
Excel 2007 dla średniozaawansowanych Zajęcia z Prowadzący: Artur Kołos.
C++ mgr inż. Tomasz Turba Politechnika Opolska 2016.
Liczby 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, …(i tak dalej) nazywamy liczbami naturalnymi. Tak jak z liter tworzy się słowa, tak z cyfr tworzymy liczby. Dowolną.
Rekurencja - Haskell Bartosz Pawlak Sebastian Żółtowski Adam Stegenda Krystian Sobótka Tomasz Gołębiewski.
Listy.
DEFINICJA I ZASTOSOWANIE W JĘZYKU HASKELL
Funkcje wyższego rzędu
Liczby pierwsze: szukanie, rozmieszczenie, zastosowanie, ciekawostki. Liczby pierwsze: szukanie, rozmieszczenie, zastosowanie, ciekawostki. Kinga Cichoń.
Programowanie I Rekurencja.
Rekurencja Ponieważ w Haskellu nie mamy klasycznych pętli for czy while dlatego w wielu algorytmach musimy używać rekurencji.
Implementacja rekurencji w języku Haskell
Haskell Składnia funkcji.
Zapis prezentacji:

Rozdział 5 REKURENCJA

Rekurencja zwana również rekursją, polega na wywołaniu przez funkcję samej siebie. Algorytmy rekurencyjne zastępują w pewnym sensie iteracje. Zazwyczaj zadania rozwiązywane tą techniką są wolniejsze od iteracyjnego odpowiednika, natomiast rozwiązanie niektórych problemów jest znacznie wygodniejsze.

Rekurencja odgrywa podczas programowania w Haskellu bardzo dużą rolę. Nie istnieją w tym języku instrukcje takie jak pętla for czy do-while. Implementacja często powtarzających się czynności musi zatem zostać rozwiązana przez rekurencję. Dobrymi przykładami rekurencji są ciąg Fibonacciego oraz silnia.

Ciąg Fibonacciego

Silnia

Maximum Funkcja maximum zwraca największy element z zadanego zbioru, dlatego tez musi być zabezpieczona na wypadek gdyby zbiór był pusty, lub zawierał tylko jeden element. By ułatwić funkcji działanie, dzielimy ją na 3 wzorce.

1. Zbiór jest pusty zwracamy bład o podanej tresci. 2. Zbiór jest jednoelementowy funkcja zwraca jedyny element tablicy. 3. Zbiór wieloelementowy podana funkcji tablica ma wiecej niz jeden element. W tym miejscu działa rekurencja. Funkcja dzieli listę na head i tail, aż do momentu otrzymania listy jednoelementowej i porównuje head, z maximum tail (czyli wywołuje funkcje maximum dla tail).

Możemy tez uprościć sobie te funkcje poprzez zastosowanie funkcji max, pobierającej dwa argumenty i zwracającej większy z nich.

Przeanalizujmy teraz działanie rekurencji na podstawie funkcji maximum. Weźmy tablice liczb całkowitych [2,1,5]. Tablice dzielimy na head(2) i tail([1,5]) i wywołujemy funkcje maximum na tail. Tail jest dzielony znów na head i tail. Otrzymujemy 1 i 5 czyli dwa zbiory jednoelementowe został spełniony warunek końca rekurencji. Porównujemy 1 i 5, funkcja zwraca 5 jako większe. Porównujemy zwrócona wartość z head naszej tablicy. 5 jest oczywiście większe niż 2, zatem funkcja zwraca 5 jako największa wartość.

QuickSort w Haskellu Załóżmy, ze mamy listę elementów typu Ord do posortowania. Najefektywniej można to osiagnąć za pomocą popularnego algorytmu QuickSort. O ile jednak w językach imperatywnych taki algorytm zajmować może nawet kilkanaście linijek kodu, to jego implementacja w Haskellu jest dużo krótsza i bardziej przejrzysta.

Nagłówek funkcji wygląda tak: Warunek końca określa sytuacje, kiedy do posortowania zostaje pusta lista (co jest równoznaczne z tym, ze jest już posortowana):

Później przychodzi pora na główny algorytm, który działa w ten sposób: Elementy listy, które są mniejsze lub równe headowi są sortowane i umieszczane na początku listy, następnie wstawiany jest head, a po nim posortowane elementy większe lub równe headowi.

Później przychodzi pora na główny algorytm, który działa w ten sposób: Elementy listy, które są mniejsze lub równe headowi są sortowane i umieszczane na początku listy, następnie wstawiany jest head, a po nim posortowane elementy większe lub równe headowi.

Warto zaznaczyć, ze w tym algorytmie sortowanie wykonywane jest dwukrotnie (dla elementów mniejszych i większych od head). Tak wiec do użycia QuickSorta potrzebne będzie skorzystanie z rekurencji, która jest jednym z najważniejszych elementów programowania funkcyjnego. Do sprawdzenia, które elementy listy są większe, a które mniejsze od head zastosujemy porównanie dwóch list.

Warto zaznaczyć, ze w tym algorytmie sortowanie wykonywane jest dwukrotnie (dla elementów mniejszych i większych od head). Tak wiec do użycia QuickSorta potrzebne będzie skorzystanie z rekurencji, która jest jednym z najważniejszych elementów programowania funkcyjnego. Do sprawdzenia, które elementy listy są większe, a które mniejsze od head zastosujemy porównanie dwóch list.

Całość funkcji QuickSort w języku Haskell wygląda tak: Przykłady działania:

Myślenie rekurencyjne Chociaż wiele problemów można rozwiązać za pomocą stosowania rekurencji, istnieją także przypadki skrajne, w których użycie rekursji nie ma sensu. Na przykład: w przypadku list, takim skrajnym przypadkiem jest pusta lista, natomiast w przypadku drzewa będzie to drzewo nie posiadające żadnych dzieci.

Myślenie rekurencyjne c.d. Na podobne przypadki można sie natknąć podczas rekurencyjnego operowania na liczbach. Zazwyczaj dochodzi do tego przy stosowaniu funkcji działających na liczbach poddawanych modyfikacjom. Przykładem takiej funkcji jest silnia, która nie zadziała na rekurencyjnie na liczbach począwszy od zera, ponieważ silnie można obliczyć jedynie dla całkowitych liczb dodatnich.

Myślenie rekurencyjne c.d. Często również przypadkiem skrajnym może okazać sie identyczność. Na przykład identycznością dla mnożenia jest liczba 1, ponieważ jakakolwiek liczba pomnożona przez 1 da te sama liczbę. W przypadku sumowania list, sytuacja skrajna może być dodawanie pustej listy, której suma jest równa 0.

Myślenie rekurencyjne c.d. Często również przypadkiem skrajnym może okazać sie identyczność. Na przykład identycznością dla mnożenia jest liczba 1, ponieważ jakakolwiek liczba pomnożona przez 1 da te sama liczbę. W przypadku sumowania list, sytuacja skrajna może być dodawanie pustej listy, której suma jest równa 0.

Myślenie rekurencyjne c.d. Podsumowując: Kiedy próbujemy rozwiązać rekurencyjnie jakiś problem, dobrze jest wiedzieć jakie są przypadki, w których nie da sie dobrze zastosować rekurencji, żeby użyć ich jako przypadków skrajnych pomocnych w rozwiązaniu danego problemu.

ZADANIA Napisać funkcje rekurencyjną która obliczy długość listy Napisać funkcje rekurencyjną która z listy list utworzy jedna listę ustawiając elementy jeden po drugim Napisać funkcje rekurencyjną która wybierze k początkowych elementów listy Napisać rekurencyjnie funkcje map

Zadanie 1 dlugosc :: [a] -> Int dlugosc [] = 0 dlugosc (x:xs) = 1 + dlugosc xs dlugosc [2,3,4,8] 1 +dlugosc [3,4,8] 1+dlugosc[4,8] 1+dlugosc[8] 1+dlugosc[] 0=4

Zadanie 2 listalist :: [[a]] -> [a] listalist [] = [] listalist (x:xs) = x ++ listalist xs

Zadanie 3 take' :: Int -> [a] -> [a] take' n _ | n <= 0 = [] take' _ [] = [] take' n (x:xs) = x : take' (n-1) xs

Zadanie 4 map' :: (a -> b) -> [a] -> [b] map' f [] = [] map' f (x:xs) = [f x] ++ map' f xs

Dziękujemy za uwagę Prezentację przygotowali: Marcin Górnicki Michał Szymczak Łukasz Zaleski Mateusz Magierski