Ambos lados, revisión anteriorRevisión previaPróxima revisión | Revisión previa |
introalg:taller07_6 [2007/06/12 02:13] – nicolasw | introalg:taller07_6 [2018/08/10 03:03] (actual) – editor externo 127.0.0.1 |
---|
| |
Nos proponemos hacer un programa funcional que **cuente la frecuencia de las ocurrencias de palabras** en un texto. | Nos proponemos hacer un programa funcional que **cuente la frecuencia de las ocurrencias de palabras** en un texto. |
El tipo de la función es es siguiente: | El tipo de la función es el siguiente: |
| |
<code> | <code> |
</code> | </code> |
| |
Donde ''Palabra'' es un **sinónimo de tipo**, en este caso de un ''String'', y sirve para mejorar la legibilidad del código. | Donde ''Palabra'' es un **sinónimo de tipo**, en este caso de un ''String'', y sirve para mejorar la legibilidad del código. Para crear este sinónimo, tenemos que escribir: |
| |
<code> | <code> |
[("hola",2),("que",1)] | [("hola",2),("que",1)] |
| |
Esta función resulta de gran utilidad para **análisis estadístico de textos**, como el que se utiliza para comprimir archivos, dar importancia a las palabras en las búsquedas, detectar palabras significativas, etc. | Esta función resulta de gran utilidad para **análisis estadístico de textos**, como el que se utiliza para comprimir archivos, dar importancia a las palabras en las búsquedas en colecciones de documentos (o internet), detectar palabras significativas en documentos, etc. |
| |
| |
===== División en Palabras ===== | ===== División en Palabras ===== |
| |
Para hacer más fácil el uso de esta función tomamos de [[http://www.cs.kent.ac.uk/people/staff/sjt/craft2e/|Haskell The Craft of Functional Programming]] por Simon Thompson, la definción de una función que **parte una cadena en palabras**, para no tener que meter a mano palabra por palabra. | Para hacer más fácil el uso de esta función tomamos de [[http://www.cs.kent.ac.uk/people/staff/sjt/craft2e/|Haskell The Craft of Functional Programming]] por Simon Thompson, la definción de una función que **parte una cadena en palabras**, para no tener que meter a mano palabra por palabra, con el formato de una lista de Strings, que sería bastante pesado. |
| |
Veamos el código de "arriba para abajo" //top-down//, empezando desde la definición principal y terminando en las funciones básicas. | Veamos el código de "arriba para abajo" //top-down//, empezando desde la definición principal y terminando en las funciones básicas. |
* Defina la función //tomaMientras :: (a -> Bool) -> [a] -> [a]//, donde //tomaMientras p xs// devuelve todos los elementos mientras cumplan con el predicado //p//, al primero que no cumpla se para. Ejemplo: //tomaMientras (>0) [1,2,3,-1,3,2,1] = [1,2,3]//, //tomaMientras (=='a') "nada por aqui" = []//. | * Defina la función //tomaMientras :: (a -> Bool) -> [a] -> [a]//, donde //tomaMientras p xs// devuelve todos los elementos mientras cumplan con el predicado //p//, al primero que no cumpla se para. Ejemplo: //tomaMientras (>0) [1,2,3,-1,3,2,1] = [1,2,3]//, //tomaMientras (=='a') "nada por aqui" = []//. |
* Defina la función //tiraMientras :: (a -> Bool) -> [a] -> [a]//, donde //tiraMientras p xs// descarta todos los elementos mientras cumplan con el predicado //p//, al primero que no cumpla se para. Ejemplo: //tiraMientras (>0) [1,2,3,-1,3,2,1] = [-1,3,2,3]//, //tiraMientras (=='a') "nada por aqui" = "nada por aqui"//. | * Defina la función //tiraMientras :: (a -> Bool) -> [a] -> [a]//, donde //tiraMientras p xs// descarta todos los elementos mientras cumplan con el predicado //p//, al primero que no cumpla se para. Ejemplo: //tiraMientras (>0) [1,2,3,-1,3,2,1] = [-1,3,2,3]//, //tiraMientras (=='a') "nada por aqui" = "nada por aqui"//. |
* ?Como se llaman //tomaMientras// y //tiraMientras// en el preámbulo standard? | * ¿Cómo se llaman //tomaMientras// y //tiraMientras// en el preámbulo estándar? |
* Defina //tomaPalabra//, //tomaEspacio//, //tiraPalabra//, usando //tomaMientras//, //tiraMientras//. | * Defina //tomaPalabra//, //tomaEspacio//, //tiraPalabra//, usando //tomaMientras//, //tiraMientras//. |
| |
==== Ejercicios ==== | ==== Ejercicios ==== |
| |
* Contar cuantas palabras hay en "El Gaucho Martín Fierro". | * Contar cuántas palabras hay en "El Gaucho Martín Fierro". |
* Obtener las palabras de "El Gaucho Martín Fierro" que tienen más de 15 letras. | * Obtener las palabras de "El Gaucho Martín Fierro" que tienen más de 15 letras. |
* Observar que hay problemas con //partePalabras// y los signos de puntuación. ?Cómo mejoraría este aspecto de la función? | * Observar que hay problemas con //partePalabras// y los signos de puntuación. ¿Cómo mejoraría este aspecto de la función? |
| |
| |
agregaOcurrencia :: Palabra -> [(Palabra,Int)] -> [(Palabra,Int)] | agregaOcurrencia :: Palabra -> [(Palabra,Int)] -> [(Palabra,Int)] |
</code> | </code> |
que procesa una palabra, la definición de //frecuencia// es simplemente acumular toda la lista con esta función. | que procesa una palabra, sumando 1 al entero cada vez que se encuentra una ocurrencia de la palabra. La definición de //frecuencia// es simplemente acumular toda la lista con esta función. |
| |
| |
* Agregar //ordenaInsFrec// como un eslabón más a la cadena de funciones ''(frecuencia.(take 1000).partePalabras.leeArchivo) "14765-utf8.txt" '' para obtener en forma creciente la frecuencia de las primeras 1000 palabras de "El Gaucho Martín Fierro". | * Agregar //ordenaInsFrec// como un eslabón más a la cadena de funciones ''(frecuencia.(take 1000).partePalabras.leeArchivo) "14765-utf8.txt" '' para obtener en forma creciente la frecuencia de las primeras 1000 palabras de "El Gaucho Martín Fierro". |
* Redefinir //ordenaInsFrec// a partir de //insertaOrdFrec// y **//foldr//**. | * Redefinir //ordenaInsFrec// a partir de //insertaOrdFrec// y **//foldr//**. |
| |
| |
| |
| |
Main> :set -u | Main> :set -u |
Main> (frecuencia''.(take 100).partePalabras.leeArchivo) "14765-utf8.txt" | Main> (frecuencia''.(take 100).partePalabras.leeArchivo) "14765-utf8.txt" |
ArbolFrec_Nodo ("Palacio.",1) (ArbolFrec_Nodo ("by",3) (ArbolFrec_Nodo ("formatted",1) (ArbolFrec_Nodo ("set",1) (ArbolFrec_Nodo ("www.gutenberg.net",1) ArbolFrec_Nulo (ArbolFrec_Nodo ("this",1) (ArbolFrec_Nodo ("with",2) ... | ArbolFrec_Nodo ("Palacio.",1) (ArbolFrec_Nodo ("by",3) (ArbolFrec_Nodo ("formatted",1) (ArbolFrec_Nodo ("set",1) (ArbolFrec_Nodo ("www.gutenberg.net",1) ArbolFrec_Nulo (ArbolFrec_Nodo ("this",1) (ArbolFrec_Nodo ("with",2) ... |
| |
... y esto no se entiende nada! | ... y esto no se entiende nada! |
[("Palacio.",1),("by",3),("formatted",1),("set",1),("www.gutenberg.net",1), ... | [("Palacio.",1),("by",3),("formatted",1),("set",1),("www.gutenberg.net",1), ... |
(58403 reductions, 104322 cells) | (58403 reductions, 104322 cells) |
| |
| |
Woohoo! | Woohoo! |