1 / 21

Эффективность рекурсивных функций.

Эффективность рекурсивных функций. f 1 = f 2 = 1 f n = f n-1 + f n-2 при n > 2. -- Вычисление числа Фибоначчи, заданного порядковым номером fib :: Integer -> Integer fib 1 = 1 fib 2 = 1 fib n = fib (n-1) + fib (n-2). fib 6 fib 5 + fib 4 (fib 4 + fib 3) + fib 4

aspen
Télécharger la présentation

Эффективность рекурсивных функций.

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Эффективность рекурсивных функций. f1 = f2 = 1 fn = fn-1 + fn-2при n > 2 -- Вычисление числа Фибоначчи, заданного порядковым номером fib :: Integer -> Integer fib 1 = 1 fib 2 = 1 fib n = fib (n-1) + fib (n-2) fib6 fib 5 + fib 4 (fib 4 + fib 3) + fib 4 ((fib 3 + fib 2) + fib 3) + fib 4 (((fib 2 + fib 1) + fib 2) + fib 3) + fib 4 (((1 + 1) + 1) + (fib 2 + fib 1)) + fib 4 (3 + 2) + (fib 3 + fib 2) (3 + 2) + ((fib 2 + fib 1) + 1) (3 + 2) + ((1 + 1) + 1) 8 Кубенский А.А. Функциональное программирование. Глава 1. Элементы функционального программирования.

  2. Эффективность рекурсивных функций. Концевая рекурсия. fib :: Integer -> Integer fib' :: Integer -> Integer -> Integer -> Integer -> Integer fib' n k fk fk1 | k == n = fk | k < n = fib' n (k+1) (fk+fk1) fk fib 1 = 1 fib n = fib' n 2 1 1 fib 6 fib' 6 2 1 1 fib' 6 3 2 1 fib' 6 4 3 2 fib' 6 5 5 3 fib' 6 6 8 5 8 factorial :: Integer -> Integer factorial 0 = 1 factorial n = n * factorial (n-1) factorial :: Integer -> Integer factorial' :: Integer -> Integer -> Integer factorial n = factorial' n 1 -- (factorial' n f) == (f * n!) factorial' n f | n == 0 = f | n > 0 = factorial' (n-1) (n*f) Кубенский А.А. Функциональное программирование. Глава 1. Элементы функционального программирования.

  3. Списки в языке Haskell. [] --пустой список [1, 2, 3] -- список из заданых элементов 1:[2, 3] -- присоединение головного элемента к списку 1:(2:(3:[])) -- создание списка с помощью конструктора ':' [1..n] -- создание списка с помощью арифметической прогрессии [2, 4..20] -- арифметическая прогрессия с заданной разностью Типы списков [Integer] -- список из целых чисел: [1..10] [Char] -- список из символов (строка: "List" == ['L','i','s','t']) [(Char, Int)] -- список из кортежей:[('L', 1), ('i', 2), ('s', 3)] [[Int]] -- список из списков:[[1, 2], [3, 5..10], []] Функция суммирования элементов списка sumList :: [Integer] -> Integer sumList [] = 0 sumList (x:s) = x + sumList s sumList [1, 3, 6] 1 + sumList [3, 6] 1 + 3 + sumList [6] 1 + 3 + 6 + sumList [] 10 Кубенский А.А. Функциональное программирование. Глава 1. Элементы функционального программирования.

  4. Еще один способ вычисления факториала. factorial :: Integer -> Integer factorial n = product [1..n] Несколько стандартных операций над списком и их определения. head :: [a] -> a head (x:ls) = x head [] = error "head: empty list" tail :: [a] -> [a] tail (x:ls) = ls tail [] = error "tail: empty list" length :: [a] -> Int length (x:ls) = 1 + length ls length [] = 0 null :: [a] -> Bool null (x:ls) = False null [] = True Кубенский А.А. Функциональное программирование. Глава 1. Элементы функционального программирования.

  5. Более сложные функции обработки списков. last :: [a] -> a last [] = error "last: empty list" last [x] = x last (x:ls) = last ls init :: [a] -> [a] init [] = error "init: empty list" init [x] = [] init (x:ls) = x : init ls (!!) :: [a] -> Int -> a [] !! _ = error "(!!): empty list" (x:ls) !! 0 = x (x:ls) !! n = ls !! (n-1) (++) :: [a] -> [a] -> [a] [] ++ ls = ls (x:l1) ++ l2 = x : (l1 ++ l2) reverse :: [a] -> [a] reverse' :: [a] -> [a] -> [a] reverse ls = reverse' ls [] reverse' [] l = l reverse' (x:ls) l = reverse' ls (x:l) Кубенский А.А. Функциональное программирование. Глава 1. Элементы функционального программирования.

  6. Еще некоторые стандартные функции обработки списков. sum :: Num a => [a] -> a sum [] = 0 sum (x:t) = x + sum t take :: Int -> [a] -> [a] take _ [] = [] take n _ | n <= 0 = [] take n (x:t) = x : take (n – 1) t maximum :: Ord a => [a] -> a maximum [] = error “maximum: empty list" maximum [x] = x maximum (x:t) = max x (maximum t) zip :: [a] -> [b] -> [(a, b)] zip [] _ = [] zip _ [] = [] zip (e1:t1) (e2:t2) = (e1, e2) : zip t1 t2 unzip :: [(a,b)] -> ([a],[b]) unzip [] = ([], []) unzip ((e1,e2):t) = (e1:tail1, e2:tail2) where (tail1,tail2) = unzip t Кубенский А.А. Функциональное программирование. Глава 1. Элементы функционального программирования.

  7. 1.3. Определение новых типов данных. Определение синонимов для типов type String = [Char] type Coord = (Double, Double) type Pair a = (a, a) type Complex = Pair Double Использование синонимов find :: String -> Char -> Int find [] _ = -1 find (x:s) y | x == y = 0 | otherwise = 1 + find s y distance :: Coord -> Coord -> Double distance (x1, y1) (x2, y2) = sqrt ((x2-x1) * (x2-x1) + (y2-y1) * (y2-y1)) complexAdd :: Complex -> Complex -> Complex complexAdd (r1, i1) (r2, i2) = (r1+r2, i1+i2) swap :: Pair a -> Pair a swap (x, y) = (y, x) Кубенский А.А. Функциональное программирование. Глава 1. Элементы функционального программирования.

  8. 1.3. Определение новых типов данных. Определение конструкторов data WeekDay = Sun | Mon | Tue | Wed | Thu | Fri | Sat data Bool = False | True Использование конструкторов weekend :: WeekDay -> Bool weekend Sun = True weekend Sat = True weekend _ = False Конструкторы с параметром data Coord = Point Double Double data Pair a = Couple a a data Coord = Coord Double Double data Pair a = Pair a a Использование конструкторовс параметрами distance :: Coord -> Coord -> Double distance (Point x1 y1) (Point x2 y2) = sqrt ((x2-x1) * (x2-x1) + (y2-y1) * (y2-y1)) distance :: Coord -> Coord -> Double distance (Coord x1 y1) (Coord x2 y2) = sqrt ((x2-x1) * (x2-x1) + (y2-y1) * (y2-y1)) swap :: Pair a -> Pair a swap (Couple x y) = Couple y x swap :: Pair a -> Pair a swap (Pair x y) = Pair y x Кубенский А.А. Функциональное программирование. Глава 1. Элементы функционального программирования.

  9. Сложные типы данных. data IntList = Nil | Cons Integer IntList data List a = Nil | a :+: (List a) data [a] = [] | a : [a] sumList :: IntList -> Integer sumList Nil = 0 sumList (Cons e ls) = e + sumList ls sumList :: List Integer -> Integer sumList Nil = 0 sumList (e :+: ls) = e + sumList ls sumList :: (Num a) => List a -> a sumList Nil = 0 sumList (e :+: ls) = e + sumList ls sumList :: (Num a) => [a] -> a sumList [] = 0 sumList (e : ls) = e + sumList ls Сортировка списка. insert :: (Ord a) => a -> [a] -> [a] insert elem [] = [elem] insert elem list@(x:s) | elem < x = elem:list | otherwise = x:(insert elem s) bubble :: (Ord a) => [a] -> [a] bubble [] = [] bubble (x:s) = insert x (bubble s) Кубенский А.А. Функциональное программирование. Глава 1. Элементы функционального программирования.

  10. A B C D E F Определение и обработка двоичного дерева. data Tree a = Empty | Node (Tree a) a (Tree a) myTree :: Tree Char myTree = Node (Node (Node Empty 'D' Empty) 'B' Empty) 'A' (Node (Node Empty 'E' Empty) 'C' (Node Empty 'F' Empty)) height :: Tree a -> Int height Empty = 0 height (Node t1 _ t2) = 1 + max (height t1) (height t2) Кубенский А.А. Функциональное программирование. Глава 1. Элементы функционального программирования.

  11. 9 1 2 2 build flatten 6 4 1 6 8 8 4 9 Сортировка с помощью двоичного дерева. 4 1 8 2 6 9 sort :: (Ord a) => [a] -> [a] build :: (Ord a) => [a] -> Tree a flatten :: Tree a -> [a] sort ls = flatten (build ls) Кубенский А.А. Функциональное программирование. Глава 1. Элементы функционального программирования.

  12. Программа сортировки с помощью двоичного дерева. data Tree a = Empty | Node (Tree a) a (Tree a) sort :: (Ord a) => [a] -> [a] build :: (Ord a) => [a] -> Tree a insert :: (Ord a) => a -> Tree a -> Tree a flatten :: Tree a -> [a] sort ls = flatten (build ls) build [] = Empty build (e:ls) = insert e (build ls) insert e Empty = Node Empty e Empty insert e (Node t1 n t2) | e < n = Node (insert e t1) n t2 | e >= n = Node t1 n (insert e t2) flatten Empty = [] flatten (Node t1 n t2) = (flatten t1) ++ (n : (flatten t2)) Кубенский А.А. Функциональное программирование. Глава 1. Элементы функционального программирования.

  13. Глава 2. Средства функционального программирования 2.1. Функции высших порядков sqr :: Integer -> Integer sqr x = x * x source = [1, 2, 5, 7, 11] sqr dest = [1, 4, 25, 49, 121] dest = map sqr source map :: (Integer -> Integer) -> [Integer] -> [Integer] map :: (a -> b) -> [a] -> [b] map _ [] = [] map f (x:ls) = (f x) : (map f ls) Кубенский А.А. Функциональное программирование. Глава 2. Средства функционального программирования.

  14. Определение функций с помощью λ-выражений λ-исчисление Черча – исчисление безымянных функций sqr : λx.* x x sqr = \x -> (x * x) Кубенский А.А. Функциональное программирование. Глава 2. Средства функционального программирования.

  15. Более сложная функция, заданная с помощью λ-выражения factorial :: Integer -> Integer factorial = \n -> case n of 0 -> 1 n -> n * factorial (n-1) Конструкция case – общая форма задания выбора по образцу case expr of patt1 | cond11 -> expr11 | cond12 -> expr12 ... patt2 | cond21 -> expr21 | cond22 -> expr22 ... ... Кубенский А.А. Функциональное программирование. Глава 2. Средства функционального программирования.

  16. Еще один пример функции высшего порядка source = [ ] 1 , 2 , 5 , 7 , 11 func = + (+) seed = 0 0 + + + + + = 11 26 18 23 25 func = (:) seed = [] 1 : (2 : (5 : (7 : (11 : [])))) = [1, 2, 5, 7, 11] foldr :: (a -> b -> b) -> b -> [a] -> b foldr func seed [] = seed foldr func seed (x:ls) = func x (foldr func seed ls) Кубенский А.А. Функциональное программирование. Глава 2. Средства функционального программирования.

  17. С помощью функций высшего порядка можно программировать. factorial :: Integer -> Integer factorial n = foldr (*) 1 [1..n] search :: (Eq a) => a -> [a] -> Bool search e list = foldr (||) False (map (\x -> x == e) list) search 5 [1, 2, 5, 7, 11] foldr (||) False (map (\x -> x == 5) [1, 2, 5, 7, 11]) foldr (||) False [False, False, True, False, False] False || (False || (True || (False || (False || False)))) True join1 :: [a] -> [a] -> [a] join1 [] list = list join1 (x:ls) list = x : (join1 ls list) join2 :: [a] -> [a] -> [a] join2 lis1 lis2 = foldr (:) lis2 lis1 Кубенский А.А. Функциональное программирование. Глава 2. Средства функционального программирования.

  18. Еще несколько полезных функций высших порядков. -- "левая вставка" – еще один способ свертки списка foldl :: (b -> a -> b) -> b -> [a] -> b foldl _ seed [] = seed foldl f seed (x:ls) = foldl f (f seed x) ls reverse :: [a] -> [a] reverse list = foldl app [] list where app l x = x:l flip :: (a -> b -> c) -> (b -> a -> c) flip f = f' where f' x y = f y x reverse :: [a] -> [a] reverse list = foldl (flip (:)) [] list :: (b -> c) -> (a -> b) -> (a -> c) = fg where fg x = f (g x) comp comp f g (.) f . g sqr :: (Num a) => a -> a sqr a = a * a power4 :: (Num a) => a -> a power4 = comp sqr sqr sqr . sqr Кубенский А.А. Функциональное программирование. Глава 2. Средства функционального программирования.

  19. Еще несколько полезных функций высших порядков. -- свертки без "зерна" foldl1, foldr1 :: (a-> a -> a) -> [a] -> a foldl1 _ [x] = x foldl1 f (x:ls) = foldl f x ls foldr1 _ [x] = x foldr1 f (x:ls) = f x (foldr1 f ls) all, any :: (a -> Bool) -> Bool all f list = foldr (&&) True (map f list) any f list = foldr (||) False (map f list) takeWhile :: (a -> Bool) -> [a] -> [a] takeWhile _ [] = [] takeWhile f (x:ls) | f x = x : takeWhile f ls | otherwise = [] zipWith :: (a -> b -> c) -> [a] -> [b] -> [c] zipWith _ [] _ = [] zipWith _ _ [] = [] zipWith f (e1:t1) (e2:t2) = (f e1 e2) : zipWith f t1 t2 -- кстати, zip list1 list2 = zipWith (,) list1 list2 Кубенский А.А. Функциональное программирование. Глава 2. Средства функционального программирования.

  20. A B C D E F Свертки сложных структур данных. data Tree a = Empty | Node (Tree a) a (Tree a) t1 = Правосторонний обход этого дерева: F, C, E, A, B, D Функция, осуществляющая свертку в порядке правостороннего обхода: foldTree (++) seed t1 => D ++ (B ++ (A ++ (E ++ (C ++ (F ++ seed))))) foldTree :: (a -> b -> b) -> b -> Tree a -> b foldTree _ seed Empty = seed foldTree f seed (Node t1 n t2) = foldTree f (f n (foldTree f seed t2)) t1 «Разглаживание» дерева с помощью foldTree: flatten :: Tree a -> [a] flatten t = foldTree (:) [] t Кубенский А.А. Функциональное программирование. Глава 2. Средства функционального программирования.

  21. Сортировка с помощью дерева: используем функции высших порядков. data Tree a = Empty | Node (Tree a) a (Tree a) sort :: (Ord a) => [a] -> [a] build :: (Ord a) => [a] -> Tree a insert :: (Ord a) => a -> Tree a -> Tree a flatten :: Tree a -> [a] sort ls = flatten (build ls) insert e Empty = Node Empty e Empty insert e (Node t1 n t2) | e < n = Node (insert e t1) n t2 | e >= n = Node t1 n (insert e t2) foldTree :: (a -> b -> b) -> b -> Tree a -> b foldTree _ seed Empty = seed foldTree f seed (Node t1 n t2) = foldTree f (f n (foldTree f seed t2)) t1 build [] = Empty build (e:ls) = insert e (build ls) flatten Empty = [] flatten (Node t1 n t2) = (flatten t1) ++ (n : (flatten t2)) build list = foldr insert Empty list flatten tree = foldTree (:) [] tree Кубенский А.А. Функциональное программирование. Глава 2. Средства функционального программирования.

More Related