¿Cómo se puede ordenar una larga lista de datos (cadenas, flotadores, etc.) que se lee desde un gran archivo (digamos unos pocos millones de líneas) utilizando un objeto Data.Vector.Generic.Mutable y un algoritmo de ordenación de Datos. Vector.Algorithms?¿Cómo se clasifica con Data.Vector.Generic.Mutable?
Respuesta
He aquí cómo hacerlo en el caso general.
En primer lugar, necesita un vector mutable. Puede construir esto incrementalmente como escanea el archivo; asigne un vector que sea lo más grande que necesite, y aumente el tamaño y cópielo cuando se quede sin espacio. O bien, puede leer todo el archivo, contar los separadores de registros y asignar la cantidad correcta de espacio a la vez. Esto es más fácil pero probablemente no aceptable en la vida real. (La estrategia de expandir según sea necesario es bastante común en ; si alguna vez usa un lenguaje como Perl y líneas de inserción, lee de un archivo al final de una matriz, esto es lo que está sucediendo. Perl asigna un espacio para una matriz , cuando lo llenas, que aumenta la cantidad de espacio de , asigna un nuevo espacio, y las copias.)
de todos modos, soy demasiado perezoso para hacer esto, así que sólo voy a crear un vector con un poco de azar números en ella.
necesitamos un montón de bibliotecas para esto:
import Control.Monad
import System.Random
import qualified Data.Vector as IV
import qualified Data.Vector.Mutable as MV
import qualified Data.Vector.Generic as V
import qualified Data.Vector.Algorithms.Intro as VA
No necesitamos todo esto a la vez, pero vamos a lo necesitamos, finalmente, por lo que pensé que tendría que salir de la camino.
De todos modos, nuestro vector mutable va a ser un vector mutable "normal", aquí MV.MVector
.
La idea de un vector mutable es que usted lo cree y lo modifique en un número de pasos . En Haskell, hay algunas maneras de hacer que esto se vea como puro al código de llamada; uno es hacerlo todo dentro de la mónada ST
. Su acción ST está creando el vector, modificándolo y "congelando" el en un vector inmutable. Internamente, está utilizando operaciones rápidas modify-this-memory-location-a-bunch-of-times, pero externamente, tiene algo que es puro. (Lea el artículo sobre ST
si quieres un argumento de por qué esto es seguro.)
Otra manera de tratar con los datos mutables es sólo lo hacen en el interior del Todo, erm, IO
, mónada. Eso es lo que vamos a hacer aquí, como es más conveniente.
(Data.Vector.Mutable
tiene dos tipos de vectores predefinidos para que, IOVector
y STVector
. Estamos utilizando IOVector
, que pone todos los las operaciones vectoriales en IO
.) Hace
Así como los párrafos 8, que íbamos a crear un vector mutable a ordenar. Y aquí estamos:
randVector :: IO (MV.IOVector Int)
randVector = do
v <- MV.new 10
forM [0..9] $ \x -> do
r <- randomIO :: IO Int
MV.write v x r
return v
Esta es una acción IO que devuelve un nuevo vector mutable con 10 números aleatorios en su interior.(Generación de números aleatorios también puede ser convenientemente levantado en el mónada IO, así que tuvimos que también, por conveniencia! Es que estamos escribiendo C, pero con más agradable sintaxis y más seguridad de tipos.)
Eso es en realidad el parte dura Para hacer la clasificación, importé Data.Vector.Algorithms.Intro
, que es básicamente una ruta rápida en el lugar . Una función llamada sort
hace la clasificación real (en cualquiera que sea la mónada del vector mutable).
Una acción que crea el vector mutable al azar y la ordena en su lugar parece:
sort = VA.sort =<< randVector
Ahora, para imprimir de eso, todo lo que tenemos que hacer es "congelar" el vector en un inmutable Vector, e imprima el .toList
. O puede simplemente iterar sobre cada elemento e imprimirlo.
Esto es lo que se me ocurrió como un ejemplo:
main = do
v <- randVector
VA.sort v
iv <- V.unsafeFreeze v :: IO (IV.Vector Int)
print . V.toList $ iv
V.unsafeFreeze
es de Data.Vector.Generic
(forma de interactuar con todos los tipos de vectores con la misma API), como es V.toList
.
De todos modos, vale la pena señalar que IO es puramente por conveniencia aquí. Dado que está construyendo un vector a partir de datos de archivos, es apropiado. 99% del tiempo, sin embargo, debe usar ST
. En su acción ST, cree el vector, ordénelo, congélelo y devuelva la versión congelada.
Un ejemplo similar usando STVector
:
randVector :: ST s (Vector Int)
randVector = do
vec <- new 10
rand <- newSTRef 17
forM_ [0..9] $ \index -> do
randN <- readSTRef rand
let randN' = (fst . next . mkStdGen) randN
writeSTRef rand randN'
write vec index randN'
unsafeFreeze vec
A continuación, ejecute con:
*Main> runST randVector
fromList [679560,1422110406,306332632,1905242129,692062628,393451229,355476175,1240028023,873588529,1181443777] :: Data.Vector.Vector
Gracias por su ayuda jrockway. Me siento cómodo con la mónada IO, pero claramente necesito aprender sobre la mónada ST. Una vez que obtenga su código de ejemplo en funcionamiento, intentaré modificarlo para leer desde un archivo y cargar el vector en lugar de números aleatorios. – Max
Gracias, gracias, gracias. Muy apreciada la introducción a ST, con buenos ejemplos de uso general. – Benjamin
- 1. ¿Cómo se clasifica el método LINQ .distinct?
- 2. ¿Cómo clasifica .NET caracteres especiales?
- 3. MapReduce - Cómo se clasifica la salida por valor
- 4. ¿Cómo clasifica Python una lista de tuplas?
- 5. ¿Cómo clasifica el servidor SQL sus datos?
- 6. NLP clasifica oraciones/párrafo como gracioso
- 7. ¿Cómo se clasifica una ArrayList de HashMaps que contiene varios pares clave-valor cada uno?
- 8. Distinto, cuenta y clasifica en una consulta sql
- 9. Almacenamiento en caché en Node Express: ¿Cómo clasifica como lista blanca/lista negra?
- 10. ¿Qué clasifica Google como operación de escritura del almacén de datos en Google App Engine?
- 11. ¿Cómo se lanza con Git?
- 12. ¿Cómo se ramifica y se fusiona con TortoiseSVN?
- 13. ¿Cómo se manejan los subproyectos con autotools?
- 14. ¿Cómo se configura applicationIconBadgeNumber con scheduleLocalNotification?
- 15. ¿Cómo se registra un usuario con Oauth?
- 16. ¿Cómo se compara Archiva con Nexus?
- 17. ¿Cómo se configura Syntastic con JSHint?
- 18. ¿Cómo se relaciona Jira con git?
- 19. Con FileStreamResult, ¿cómo se cierra MemoryStream?
- 20. ¿Cómo anidar se une con CakePHP?
- 21. ¿Cómo se usa menos css con django?
- 22. ¿Cómo se diseñan sistemas complejos con TDD?
- 23. ¿Cómo se compara Hive con HBase?
- 24. ¿Cómo se usa LINQ con Sqlite
- 25. ¿Cómo se comprueban las cookies con Chrome?
- 26. ¿Cómo se dibujan polígonos transparentes con Python?
- 27. ¿Cómo se puede desplazar legítimamente con GDI +?
- 28. ¿Cómo se integra con Spring ScalaTest
- 29. ¿Cómo se depuran las funciones con postgres?
- 30. ¿Cómo se compara RabbitMQ con Mule?
También, Data.Vector.Generic.Mutable no es un objeto, que es una API abstracta para la manipulación de cualquier tipo de vector mutable Estos incluyen Data.Vector.Unboxed.Mutable, Data.Vector.Storable.Mutable, etc. – jrockway