Сошников Дмитрий Валерьевич к.ф.-м.н., доцент [email protected] Факультет инноваций и высоких технологий Московский физико-технический институт
Jan 21, 2016
Сошников Дмитрий Валерьевич
к.ф.-м.н., доцент[email protected]
Факультет инноваций и высоких технологий
Московский физико-технический институт
Лекция 11
Функциональные структуры данных
3
©20
08 С
ошни
ков
Д.В
.
В зависимости от решаемых задач для эффективного решения приходится использовать специфические структуры данных
Chris Okasaki, Purely Functional Data Structures, 1996.
4
©20
08 С
ошни
ков
Д.В
.
Наивная реализация head / tail – вставка в начало – O(1) put – вставка в конец – O(n)
type 'a queue = 'a list;;
let rec put x = function [] -> [x]| h::t -> h::snoc x t;;
// hd, tl – the same as for List
5
©20
08 С
ошни
ков
Д.В
.
Два списка 1,2,3,4,5 => [1,2,3],[5,4] Добавляем ко второму, берем из первого Если первый становится пустым – перестраиваем Первый список пустой только для пустой очереди Все операции – O(1) [не считая периодической
перестройки]
type 'a queue = 'a list * 'a list;;
let tail (L,R) = match L with [x] -> (rev R, []) | h::t -> (t,R);;
let head (h::_,_) = h;;
let put x (L,R) = match L with [] -> ([x],R) | _ -> (L,x::R);;
©20
08 С
ошни
ков
Д.В
.
6
F# - частично-императивный язык, содержит mutable-типы данных
Тип массив (T []) во многом напоминает список, но является mutable: Операции не возвращают новый массив, а
модифицируют исходный Соответствует массивам .NET (интероперабельны с
ними)let a = [|1;2;3|];;a.[1];;a.[1] <- 4;;a.[1..2];;a.[..2];;
let incr a = for i=0 to Array.length a-1 do a.[i] <- a.[i]+1 done;;let incr a = Array.iteri (fun i x -> a.[i] <- a.[i]+1) a;;
©20
08 С
ошни
ков
Д.В
.
7
При программировании на F# бывает удобно использовать типы, определенные в .NET Framework
Они почти всегда mutable, но можно их использовать в immutable-контексте
Полезно знать: ResizeArray – соответствует List<T>
в .NET Dictionary <T1,T2>
©20
08 С
ошни
ков
Д.В
.
8
©20
08 С
ошни
ков
Д.В
.
9
Вычисление треугольника Паскаля
1 11 2 1
1 3 3 11 4 6 4 1
.......
let pascal n = let rec pas L n = let A::t = L in if n = 0 then L else pas (( (1:: [for i=1 to length A-1 -> A.[i-1]+A.[i]]) @[1]) ::L) (n-1) in pas [[1;1]] n;;
10
©20
08 С
ошни
ков
Д.В
.
Рекурсивные структуры данных – часто используемый удобный механизм хранения данных в функциональном программировании
Списки – гармоничная часть языка Прозрачный синтаксис (специальный синтаксис
конструкторов) Поддержка со стороны библиотеки
Множество абстрактных функций для обработки списков позволяет, комбинируя их, легко реализовывать различные алгоритмы обработки
11