Escolar Documentos
Profissional Documentos
Cultura Documentos
1. Objetivos
Permitirle diseñar e implementar su propia estructura de datos.
2. Honestidad Académica
Puede leer el código de conducta en: http://soporte.code-fu.net.ni/codigo-de-conducta-
con-el-curso/
3. Evaluación
Su trabajo en este PSet se evaluará a lo largo de cuatro ejes principalmente.
3.1. Alcance
¿En qué medida su código implementa las características requeridas por nuestra
especificación?
3.2. Exactitud
¿Hasta qué punto su código está libre de errores?
3.3. Diseño
¿En qué medida está su código bien escrito (claramente, eficientemente, elegante-
mente, y/o lógicamente)?
3.4. Estilo
¿En qué medida es su código legible (comentado, sangrado, con variables adecua-
damente nombradas)?
update50
Como en el Problem Set 4, este Problem Set viene con cierto código de distribución que
necesitarás descargar antes de empezar. Ejecutá
cd ∼/workspace
wget http://cdn.cs50.net/2015/fall/psets/5/pset5/pset5.zip
para descargar un ZIP del distro de este problem set. Si luego ejecutás
ls
deberías ver que ahora tenes un archivo llamado pset5.zip en tu directorio ∼/workspace .
Descomprimelo al ejecutar lo siguiente.
Si luego ejecutás
ls
rm -f pset5.zip
cd pset5
Ahora, ejecutá
ls
¡Interesante!
¡El reto que tiene por delante es implementar el programa revisión de deletreo más rápido
que pueda! Por "más rápido", estamos hablando de tiempo real, notable—nada de esa
cosa asintótica esta vez.
En speller.c , hemos creado un programa que está diseñado para verificar el deletreo
de las palabras de un archivo después de cargar un diccionario de palabras del disco a
la memoria. Desafortunadamente, no implementamos la sección de carga. O la parte de
verificación. ¡Ambos (y un poco más) te lo dejamos a ti!
Vamos a empezar.
5.1. Makefile
Recuerde que make automatiza la compilación de su código para que no tenga que
ejecutar clang manualmente junto con un montón de interruptores. Sin embargo, a
medida que sus programas crecen en tamaño, make no podrá inferir por contexto cómo
compilar su código; tendrá que empezar a decir cómo compilar su programa, en particular
cuando se trata de varios archivos de origen (i.e., .c ), como en el caso de este conjunto
de problemas. Así que vamos a utilizar un Makefile , una configuración que le dice a
make exactamente qué hacer. Abra Makefile , y vamos a hacer un recorrido por sus
líneas.
La línea de abajo define una variable llamada CC que especifica que make debería usar
clang para compilar.
CC = clang
La línea de abajo define una variable llamada EXE , cuyo valor sera el nombre de nuestro
programa.
EXE = spelller
La línea de abajo define una variable llamada HDRS , cuyo valor es una lista de archivos
de cabecera usados por speller .
HDRS = dictionary.h
La línea de abajo define una variable llamada LIBS , cuyo valor debería ser una lista de
bibliotecass separadas por espacios, las cuales deben ser prefijadas con -l . (Recuarde
que usamos -lcs50 anteriormente.) Lo más probable es que no necesite enumerar ninguna
biblioteca para este conjunto de problemas, pero hemos incluido la variable por si acaso.
LIBS =
La línea de abajo define una variable llamada SRCS , cuyo valor es una lista de archivos
C separadas por espacios que van a implementar colectivamente speller.
La linea de abajo define una variable llamada OBJS , cuyo valor es igual al de SRCS ,
except that each file’s extension is not .c but .o .
Las líneas de abajo definen un "targetüsando estas variables que le dicen a make como
compilar speller.
La línea de abajo específica que nuestros archivos .o todos “dependan de” dictionary.h
y Makefile tal que cambios a cualquiera de los dos induce la recompilación del otro al
correr make .
Finalmente, las líneas de abajo definen otro “target” para limpiar el directorio del Problem
Set.
clean:
rm -f core $(EXE) *.o
Sepa que puede modificar este Makefile como mejor le parezca. De hecho debe, si crea
cualquier archivo .c o .h propio. Pero asegúrese de no cambiar ninguna tabulacion
(es decir, \t ) A los espacios, ya que make espera que el primero esté presente debajo
de cada "target".
El effecto en conjunto de todas estas líneas es que usted puede compilar speller con
un solo comando, a pesar que contiene varios archivos:
make speller
make
Y si alguna vez quiere borrar speller y cualquier core o archivos .o , tambien puede
hacerlo con un solo comando:
make clean
En general, sin embargo, cada vez que desee compilar el código para este conjunto de
problemas, debería bastar con correr:
make
5.2. speller.c
Ok, a continuación, abra speller.c y pase un tiempo mirando el código y los comenta-
rios en él. No necesitará cambiar nada en este archivo, pero debe comprenderlo. Observe
cómo, a través de getrusage , vamos a estar “benchmarking” (es decir, midiendo el
tiempo de ejecución de) sus implementaciones de check , load , size y unload . Tam-
bién observe cómo vamos a pasar a check , palabra por palabra, el contenido de algún
archivo para ser chequeado de forma ortográfica. En última instancia, informamos cada
error ortográfico en ese archivo junto con un montón de estadísticas.
Note que hemos definido el uso de speller como:
donde dictionary se supone que es un archivo que contiene una lista de palabras
en minúscula, una por línea, y text es un archivo para ser verificado por ortografía.
Como sugieren los corchetes, la provisión de dictionary es opcional; si se omite este
./speller text
donde text es el archivo al que usted le desea revisar la ortografía. Basta con decir, el
primero es más fácil de escribir! (Por supuesto, speller no podrá cargar ningún diccionario
hasta que implemente load en dictionary.c ! Hasta entonces, verás Could not load.)
Tenga en cuenta que por defecto dentro del diccionario, son 143,091 palabras, todas
las cuales deben ser cargadas en la memoria! De hecho, eche un vistazo a ese archivo
para tener una idea de su estructura y tamaño. Observe que cada palabra en ese archivo
aparece en minúsculas (incluso, por simplicidad, nombres propios y siglas). De arriba a
abajo, el archivo se clasifica lexicográficamente, con sólo una palabra por línea (cada
una termina con \ n ). Ninguna palabra tiene más de 45 caracteres, y ninguna palabra
aparece más de una vez. Durante el desarrollo, puede resultar útil proveer a speller con
un dictionary hecho por usted que contenga menos palabras, de modo que no tenga
problemas para depurar una enorme estructura en la memoria. En dictionaries/small es
uno de esos diccionarios. Para usarlo, ejecute
donde text es el archivo que desea chequear. No avance hasta que este seguro usted
entienda como speller funciona.
Lo mas probable, es que no paso suficiente tiempo revisando speller.c . Retroceda un
paso y pase por él una vez mas.
5.3. questions.txt
Bueno, técnicamente ese último problema indujo un bucle infinito. Pero asumiremos que
2. ¿Por esa misma página de man , cuántos miembros hay en una variable de tipo
struct rusage ?
3. ¿Porqué cree usted que pasamos before y after por referencia (en vez de por
valor) para calculate , a pesar de que no cambiamos sus contenidos?
4. Explicar con la mayor precisión posible, en un párrafo o más, cómo main lee
palabras de un archivo. En otras palabras, convencernos de que usted realmente
entiende cómo funciona el bucle for de esa función.
5. ¿Por qué crees que usamos fgetc para leer los caracteres de cada palabra una a
la vez en lugar de usar fscanf con una cadena de formato como " % s"para leer
palabras completas de una vez? Dicho de otra manera, ¿qué problemas pueden
surgir al dependiendo solo en fscanf ?
6. ¿Porqué cree que declaramos los parametros de check y load como const ?
5.4. texts
Para que puedas probar la implementación de speller , también te hemos proporcionado
un montón de textos, entre ellos el guión de Austin Powers: El Agente Internacional
del Misterio, un sonido de Ralph Wiggum, tres millones de bytes de Tolstoy, algunos
fragmentos de Maquiavelo y Shakespeare, la totalidad de la Biblia King James V, y más.
Para que sepas qué esperar, abre y desplaza cada uno de esos archivos, todos los cuales
están en un directorio llamado text dentro de tu directorio pset5 .
Ahora, como debes saber al leer sobre speller.c cuidadosamente, la salida de speller , si
ejecutada por ejemplo con,
./speller texts/austinpowers.txt
∼cs50/pset5/speller texts/austinpowers.txt
MISSPELLED WORDS
[...]
Bigglesworth
[...]
Virtucon
[...]
friggin'
[...]
trippy
[...]
WORDS MISSPELLED:
WORDS IN DICTIONARY:
WORDS IN TEXT:
TIME IN load:
TIME IN check:
TIME IN size:
TIME IN unload:
TIME IN TOTAL:
TIME IN LOAD representa el número de segundos que speller tarda en ejecutar tu im-
plementación de load . TIME IN check representa el número de segundos que speller
tarda en ejecutar tu implementación de check . TIME IN size representa el número de
segundos que speller tarda en ejecutar tu implementación de size . TIME IN unload
representa el número de segundos que speller tarda en ejecutar tu implementación de
unload . TIME IN TOTAL es la suma de aquellas cuatro medidas.
Note que estos tiempos pueden variar algo entre las ejecuciones de speller ,
dependiendo en que mas el CS50 IDE está haciendo, incluso si no has cambiado
tu código.
Por cierto, para ser claros, por “misspelled”(mal deletrado, en español), simplmenete nos
referimos a que cierta palabra no está en el dictionary provided.
6. Spell Checking
Bien, ahora el reto frente a vos es implementar load , check , size y unload
tan eficientemente como sea posible, de forma que TIME IN load , TIME IN check ,
TIME IN size , y TIME IN unload estén todos minimizados. Para estar seguros, no es
obvio lo que siquiera significa ser minimizado, en tanto como estas referencias ciertamen-
te van a variar mientras alimentás a speller con diferentes valores para dictionary
y para text . Pero en esto yace el reto, por no decir que la parte divertida, del problema
set. El problem set es tu oportunidad para diseñar. A pesar de que te invitamos a mini-
mizar espacio, tu enemigo definitivo es el tiempo. Pero antes de que te metás de cabeza
en esto, te daremos algunas especificaciones.
Usted puede alterar dictionary.c (y, de hecho, debe hacerlo para completar las
implementaciones de load , check , size , y unload ), pero no puede alterar
las delclaraciones de load , check , size , y unload ).
Usted puede investigar funciones has en libros o en la Web, siempre y cuando usted
cite el origen de cualquier función hash que integre en su código
6.1. load
¡Implemente load !
Permítanos sugerirle que tome algunos diccionarios más pequeños que el predefinido de
143, 091 palabras con los cuales probar su código durante el desarrollo. Y aquí está
Zamyla con algo de ayuda extra:
https://www.youtube.com/watch?v=E_1D17P-bM0
6.2. check
¡Implemente check !
Permítanos sugerirle que tome algunos pegueños archivos para hacer spell-check (revisión
de deletreo) antes de intentar. Aquí está Zamyla de nuevo:
https://www.youtube.com/watch?v=r7CVY6O-XJw
6.3. size
¡Implemente size !
Si usted ejecuta valgrind sin especificar un text para speller , sus implementa-
ciones de load y unload no serán llamadas (ni analizadas).
Y no se olvide de su otro buen camarada, gdb .
./speller texts/austinpowers.txt
Y luego usted podría correr la solución del staff sobre el mismo texto en otra ventana, a
como se hace a continuación
Luego, podría comparar las ventanas visualmente. Aunque, eso podría volverse tedioso
rápidamente. Así que en vez de eso, podría querer “redirigir” el output de su programa
hacia un archivo (justo como usted pudo haber hecho con generate en Problem Set
3), a como se muesrta a continuación.
Usted puede entonces comparar ambos archivos lado a lado en la misma ventana con un
programa como diff , a como se musetra a continuación.
Alternativamente, para ahorrar tiempo, usted podría solo comparar el out de su programa
(asumiendo que usted lo redirigió, por ejemplo, student.txt ) con una de las claves de
respuesta sin correr la solución del staff, a como se muestra a continuación.
Si el output de su programa encaja con el del staff, diff generará dos columnas que
deberían ser idénticas excepto por, quizá, la cantidad de veces que se corre, al fondo.
Aunque si las columnas difieren, usted verá > o | donde difieran. Por ejemplo, si usted
ve (siguiente página):
FOTTAGE FOTTAGE
INT INT
>EVIL'S
s s
>EVIL'S
Farbissina Farbissina
significa que su programa (cuyo output está a la izquierda) no piensa que EVIL’S esté
mal escrito, incluso si el out del staff (a la derecha) sí lo hace, a como es implicado por la
ausencia de EVIL’S en el la columna izquierda y la presencia de EVIL’S en la columna
derecha.
Para probar su código de forma menos manual (aunque incluso más exhaustivamente),
usted puede ejecutar lo que se muestra a continuación.
check50 cs50/2017/x/speller
Note que check50 no busca fugas de memoria, así que también asegúrese de correr
valgrind a como fue dicho.
¿Cómo evaluar cuán rápido (y correcto) es nuestro código? Bueno, a como siempre,
siéntase libre de jugar con la solución del staff, a través del siguiente comando, y compare
estos números con los suyos.
∼cs50/pset5/speller texts/austinpowers.txt
7.2. questions.txt
¡Felicitaciones! En este punto, su speller-checker (corrector de deletreo) es presumible-
mente completo (y rápido), así que es tiempo de la interrogación. En questions.txt ,
responda cada una de las siguientes preguntas en un párrafo corto.
7. ¿Qué estructura de datos utilizó para implementar su spell-checker? Asegúrese de
no dejar su respuesta en solo “hash table”, “árboles” o algo similar. Exponga lo
que hay dentro de sus “nodos”.
8. ¿Qué tan lento fue tu código la primera vez que lograste que trabajara correcta-
mente?
9. ¿Qué tipos de cambios, si hubo alguno, hiciste en tu código para mejorar su desem-
peño.
10. ¿Siente que su código tiene algún cuelo de botella que no fuiste capaz de superar?
Rellene todos los datos que se le solicitan o acceda con una de sus redes sociales
(es preferencial).
Una vez que se registró diríjase a cs50.io y será redirigido a una página donde
deberá escoger la opción edX como CS50 ID (dé clic en Submit).
Una vez que ha accedido ya podrá compartir su Workspace dando clic en el botón
Share ubicado en la parte superior derecha.
Dentro del mismo formulario en la sección Invite People escriba silfdv y pro-
porcione permisos de escritura (botón RW), luego de clic en Invite, le debería
aparecer lo siguiente: