Arrays
El array o vector es un contenedor que
almacena una colección de datos del
mismo tipo, de modo que cada dato
almacenado tiene asociada una posición.
Una implementación ineficiente,
mediante listas
• type Array a = [a]
• creaArray :: [a]-> Array a
• creaArray xs = xs
• ar :: Array Char
• ar = creaArray['a'..'d']
Si consideremos que las posiciones
correspondientes a un array de n
elementos están en el rango [0..n-1]
, podemos seleccionar el elemento
que ocupa cierta posición, con :
•
•
•
•
•
infixl 9 !
(!) :: Array a -> Integer->a
(x:_)!0 = x
(_:xs)!(n+1) = xs ! n
_ !_ = error " (!): Posición no válida"
El operador que permite obtener un
nuevo array modificando el elemento
almacenado en cierta posición es :
• infixl 8 =:
• (=:) :: Array a -> (Integer,a) -> Array
a
• (x:xs) =: (0,y) = (y:xs)
• (x:xs) =: (n+1,y) = x:(xs =: (n,y))
• _ =: _ = error " (=:): Posición no
válida"
Es posible introducir definiciones
locales en cualquier parte de una
expresión usando las palabras let e in
•
•
•
•
•
•
Main> let br = ar =: (3,'z') in br
"abcz" :: [Char]
Main> let br = ar =: (3,'z') in br ! 3
'z' :: Char
Main> let br = ar =: (3,'z') in br ! 2
'c' :: Char
Por asociatividad del operador =: es
posible realizar varias modificaciones
de un modo compacto
• Main> let br = ar =: (0,'A')=:(3,'Z')in
br
• "AbcZ" :: [Char]
• Main> let br = ar =: (0,'A')=:(3,'Z')in
(br ! 0,br !1,br ! 2, br ! 3)
• ('A','b','c','Z') ::
(Char,Char,Char,Char)
Es posible representar una matriz
mediante un array de arrays
• type Matriz = Array (Array Float)
• matriz :: Int -> Matriz
• matriz n = creaArray (replicate n
creaFila)
• where
• creaFila = creaArray(replicate n 0.0)
El principal problema, de la
implementación de arrays mediante listas
es la falta de eficiencia, pues para acceder
o modificar el último elemento del array es
necesario pasar por todos los que le
preceden, por lo que en el peor caso se
realizarán tantas llamadas recursivas como
tamaño tenga el array.
Una implementación más eficiente de
arrays se realiza mediante árboles
binarios. Con esta implementación, un
array de n elementos se representará
mediante un árbol de altura lg n , de modo
que en el peor de los casos las operaciones
(!) y (=:) serán tambien de ese orden.
Una implementación
eficiente
data ArbolH a = HojaH a | NodoH (ArbolH a)(ArbolH a) deriving Show
type Array a = ArbolH a
-----------------------------------------------------------creaArray :: [a] -> Array a
creaArray [x] = HojaH x
creaArray xs @ (_:_:_)= NodoH (creaArray i)(creaArray d)
where
(i,d) = partir xs
partir :: [a] -> ([a],[a])
partir [] = ([],[])
partir [x] = ([x],[])
partir (x:y:zs) = (x:xs,y:ys)
where
(xs,ys)= partir zs
infixl 9 !
(!) :: Array a -> Integer -> a
HojaH x ! 0 = x
NodoH i d ! n = if even n then
i ! (n `div` 2)
else
d ! (n `div` 2)
_ ! _ = error "posición no válida"
•
•
•
•
•
•
•
•
infixl 8 =:
(=:) :: Array a -> (Integer,a) -> Array a
HojaH x =: (0,y) = HojaH y
NodoH i d =: (n,y) = if even n then
NodoH (i =: (n `div` 2,y)) d
else
NodoH i (d =: (n `div` 2,y))
_ =: _ = error "(=:): posición no válida"