Buenas, pues ya hace un par de meses que deje la programación por falta de tiempo y quiero retomarla para no perder la practica y que mejor forma de hacerlo que resolviendo algunos problemas, no son muy avanzados mis conocimientos, pero creo que me valdrán para hacer el siguiente problema:
CitarUna agencia de publicidad está diseñando un catálogo, organizado en capítulos. Para
hacer más atractivo el diseño gráfico, en cada página quiere poner un fondo en un color
suave que contenga una secuencia de letras que, sin ser el nombre completo del
capítulo, ni una letra aislada, lo identifique sin ambigüedad, cuando esto fuera posible.
Por ejemplo, si un capítulo fuera pincel y otro pipa, se podrían utilizar como fondo
secuencias como pin, pinc, pince, pip, ipa, etc. Por el contrario, no se
podrían utilizar secuencias como pi por ser ambiguas. Llamaremos identificadores de
las palabras a las secuencias más básicas que identifican sin ambigüedad a un capítulo.
En el ejemplo que dimos, pin, pip e ipa son identificadores. pinc y pince no lo
son, dado que se forman agregando letras a secuencias más cortas.
El problema consiste en encontrar tales identificadores. La lista de nombres de capítulos
está contenida en el archivo ident.in. Cada capítulo está identificado por una sola
palabra, de hasta 15 caracteres. Hay una línea en el archivo por cada capítulo, y el fin
está indicado por una línea en blanco. En total puede suponerse que hay 20 capítulos o
menos.
La salida se debe grabar en el archivo ident.out y debe contener los identificadores
válidos para cada capítulo, en un formato similar al del ejemplo. Los identificadores
válidos son los que tienen dos o más caracteres, están contenidos en el nombre de cada
capítulo pero no son el nombre completo, lo representan sin ambigüedad, y no hay
partes de éstos que también los representen. El orden de los identificadores no es
importante.
Ejemplo: Si ident.in contiene:
papel
pincel
cinc
pipa
cincel
El archivo ident.out podría contener:
papel:
ap
pe
pincel:
pin
cinc:
pipa:
ip
cincel:
cince
Lo de trabajar con archivos lo ignoro porque no tengo ni idea de como va eso, no estoy pidiendo para nada que me deis una solución, solo que me deis alguna idea, que me orientéis un poco, porque no se por donde empezar.
Por si a alguien le interesa, el problema está extraído de la pagina de la OIA (Olimpiada Informática Argentina) en la sección de problemas.
Edito: El lenguaje que voy a utilizar es C.
Saludos
Antes que nada un fuerte saludo otra vez y gracias por la alegría que me das al verte por aquí.
Para que te hagas una idea de lo que te proponen, ya que no vas a usar ficheros pues aún no has llegado -tranqui!, todo es cuestión de tiempo- puedes imaginarte un capítulo como un array compuesto de diversas palabras. Por ejemplo suponiendo que ninguna palabra exceda de 20 caracteres:
char capitulo1[15][20]={"pincel","pipa","Cine","Teatro", ....-y así hasta quince....}
char capi1[15][20]={0};
Y lo que podrías hacer es recorrer el array capitulo1 y guardar en capi1 las palabras abreviadas. Ahí veo una pequeña laguna en cuanto al número de letras a tomar como abreviaturas de las originales. Por hacerlo de forma esquemática yo te propondría que tomaras la longitud de la palabra, que la obtienes con strlen, menos tres de forma que pincel sería pin, como ejemplo.
Se trataría en esencia de ir recorriendo con un for el array capitulo1[i]
y en otro for interno al anterior de 0 a strlen-3 guardas
los caracteres. Vamos algo así:
for (i=0;i<15;i++)
for (j=0;j<strlen(capitulo1[i])-3;j++)
{
capi1[i] [j]=capitulo1[i] [j];
}
Se podría hacer con más capítulos pero en el formato array en lugar de fichero originaría arrays tridimensionales.
Se me ocurre que para dos capítulos fuera:
char capituloi[2][15][20]={{"pincel","pipa","Cine","Teatro", ....-y así hasta quince....},{"papel","tijera", ....-y así hasta quince....}}
char capi[2][15][20]={0};
Demasiado fuerte para empezar. Te aconsejaría el primero con un sólo capítulo.
Espero haberme explicado meridianamente bien y te sirva de orientación....... y que yo no haya metido la gamba.
Saluditos!. ...... (http://st.forocoches.com/foro/images/smilies/aaaaa.gif)
P.D:Procura elegir mejor los ejercicios, éste es muy de fichero.
Buff...arrays, aun no he tocado ese tema en el libro que estoy leyendo, de hecho, terminé con las funciones y ese es el que me toca ahora, así que lo leeré y después continuo con el problema, muchas gracias, cuando lo retome miraré otra vez tus consejos.
Cita de: leosansan en 16 Mayo 2013, 21:56 PM
P.D:Procura elegir mejor los ejercicios, éste es muy de fichero.
Pues tengo muchísimos ejercicios que descargué en formato PDF de la web que nombré antes y casi todo son de archivos, aunque no me importa mucho porque puedo hacer el mismo ejercicio sin necesidad de manejar archivos (ya lo hice con otro problema de la misma web, de hecho pregunte aquí en el foro) y cuando aprenda a manejarlos me servirá de mucha práctica.
Saludos
Cita de: Caster en 16 Mayo 2013, 22:19 PM
Buff...arrays, aun no he tocado ese tema en el libro que estoy leyendo, de hecho, terminé con las funciones y ese es el que me toca ahora, así que lo leeré y después continuo con el problema, muchas gracias, cuando lo retome miraré otra vez tus consejos.
Pues ánimos y a por el tema de arrays, es fundamental porque te abrirá las puertas a muchos ejercicios.
Y casi seguro que después tendras el tema de punteros. Desde ya te aconsejo tomarlo con calma y ganas ya que es "la otra gran puerta".
Saluditos .....,nuevamente".......(http://st.forocoches.com/foro/images/smilies/ciao.gif)
Me equivoque, viene ahora el tema de la variables globales y demás tipos de variables, después arrays, y si, estabas en lo cierto, a continuación viene el tema de punteros, cuando tenga tiempo me pongo y me los leo rápido.
Saludos.
Bueno leosansan, vuelvo a retomar el problema porque ya llegué al tema de los arrays, a ver, ya me encontré con algo que no entiendo en la solución que me das, tu me dices que almacene varias palabras en el mismo capítulo, pero creo que eso no estaría acorde con lo que pide el problema, que pide una palabra (20 palabras como límite y 15 caracteres por cada palabra) y sus abreviaturas (si no entendí mal) por capítulo, y si trato con varios capítulos no se tienen porque crear arrays multidimensionales, se usa un array bidimensional por cada capítulo y solucionado.
Saludos
Cita de: Caster en 18 Mayo 2013, 14:26 PM
..................................
y si trato con varios capítulos no se tienen porque crear arrays multidimensionales, se usa un array bidimensional por cada capítulo y solucionado.
Esa es una opción totalmente válida, aunque a mi entender poco eficiente por los múltiples arrays que habría que usar, uno por capítulo,ni te cuento los que tendrías si fuera una novela rusa. :laugh:
Mientras en el array tridimensional podrías meter todos los capítulos y su manejo y referencia es más breve e inmediata.
Pero como te comente al principio no es mala idea empezar con arrays bidimensionales.
Saluditos!..... .. (http://st.forocoches.com/foro/images/smilies/aaaaa.gif)
Otra duda que me surge, tu declaras el array capitulo de la siguiente manera:
char capitulo1[15][20]
Donde 15 sería el número de filas y 20 el número de columnas, si es así, tendría que ser al reves creo:
char capitulo1[20][15]
20 sería el número máximo de palabras, y 15 el número máximo de carácteres por palabra.
Saludos
Cita de: Caster en 18 Mayo 2013, 18:34 PM
Otra duda que me surge, tu declaras el array capitulo de la siguiente manera:
char capitulo1[15][20]
Donde 15 sería el número de filas y 20 el número de columnas, si es así, tendría que ser al reves creo:
char capitulo1[20][15]
20 sería el número máximo de palabras, y 15 el número máximo de carácteres por palabra.
Justo al revés de lo que dices y como yo te pongo en el ejemplo. El primer índice hace referencia al número de palabras y el segundo al de caracteres, que te recuerdo es uno más de la palabra más larga para tener en cuenta el caracter nulo.Un ejemplo podría ser:
char oficina[3][5] = {"0210","0441","0462"};
donde como ves el primer índice igual a 3 cuenta las oficinas, en este caso determinadas por el número de sucursal, y el segundo 5 al tamaño, donde obsevaras que aunque todas las las oficinas son de cuatro caracteres, la dimensión es cinco por lo que te comenté de tener en cuenta al caracter nulo.
Saluditos!. .....(http://st.forocoches.com/foro/images/smilies/simba1.gif)
Buf...no doy avanzado, ya terminé el tema de los arrays y me puso a ello, pero no se por donde avanzar, solo tengo hecho lo que me dijiste que es esto:
#include <stdio.h>
#include <string.h>
int main()
{
char capitulo[15][20] = {"pincel", "cinc", "cincel", "pipa", "papel"};
char cap[15][20];
for (fil = 0; i<15; i++;)
{
for (col = 0; j<strlen-3; j++;)
{
capi1[fil] [col] = capitulo1[fil] [col];
}
}
return 0;
}
Estaba pensando en como imprimir las palabras abreviadas, se como escribir carácter a carácter con un for, pero no sabría como imprimir cada palabra en una linea diferente, y también me queda averiguar como hallar las abreviaturas de cada palabra, porque en este código vale para algunas palabras, pero no para todas, creo que la cosa iría porque quitar los 3 últimos caracteres en algunas palabras, y los 3 primeros en otras., o sacar la longitud de la palabra y según esta quitar mas o menos caracteres.
Saludos
Tienes varios errores comprensibles en este arranque con los arrays:
* El primer índice o bien no pones nada o, mejor pones el número de palabras que contiene el array capitulo1, 5 en este caso.
* El segundo índice no está mal ya que no se peca por exceso, pero penaliza el uso de la memoria y en este caso, como la palabra más larga es de 6 caracteres habrá que poner 7, por lo que te explique de tener en cuenta al caracter nulo de todo fin de cadena.
* En los for se te fue la olla ;) al poner fil=0 y col=0 cuando los índices son i y j, por lo que será i=0 y j=0.
* En el caso de arrys de cadenas mejor que pensar en filas y columnas, algo típico en los arrayas bidimensionales numéricos aunque en sí no esté mal, es pensar en posición de la cadena y caracter de dicha cadena.
* Al usar la función strlen no le pusiste el argumento de la misma, fíjate en el código para verlo mejor.
* Haces un uso excesivo de las llaves. Cuando un for, if o compañía sólo tiene una instrucción como "cuerpo" te la puedes y debes ahorrar, sólo enmaraña la lectura del código. Supongo que es una buena costumbre adquirida de python, como el indentar siempre el código para una buena comprensión y fácil lectura.
* Tienes un punto y coma de más al final de los for, dentro del paréntesis.
* Al final te olvidaste de la instrucción para imprimir los resultados. He aquí la salida:
pincel ---->pin
cinc ---->c
cincel ---->cin
pipa ---->p
papel ---->pa
Y con tanto rollo casi me olvido de ponerte una posible solución, se podría mejorar con el uso de otras funciones de la librería string, pero estamos a lo que estamos, el uso de arrays:
#include <stdio.h>
#include <string.h>
int main(){
int i,j;
char capitulo1[5][7] = {"pincel", "cinc", "cincel", "pipa", "papel"};
char cap1[5][7]={0};
for (i= 0; i<5; i++)
for (j = 0; j<strlen(capitulo1[i])-3; j++)
cap1[i][j] = capitulo1[i][j];
for (i = 0; i<5; i++)
printf("%s ---->%s\n",capitulo1[i],cap1[i]);
return 0;
}
Una variante para que imprima en cap1 un número de letras en función de la longitud de la cadena y así no salgan cadenas de una sola letra sería:
pincel ---->pin
cinc ---->ci
cinceles ---->cinc
pipa ---->pi
termometro ---->termo
Para esta variante del código:
#include <stdio.h>
#include <string.h>
int main(){
int i,j,longitud;
char capitulo1[5][11] = {"pincel", "cinc", "cinceles", "pipa", "termometro"};
char cap1[5][11]={0};
for (i= 0; i<5; i++){
longitud=strlen(capitulo1[i])/2;
for (j = 0;j<longitud; j++)
cap1[i][j] = capitulo1[i][j];
}
for (i = 0; i<5; i++)
printf("%s ---->%s\n",capitulo1[i],cap1[i]);
return 0;
}
Espero no haberte agobiado con tantas sugerencias de un tirón pero sabes que para cualquier otra duda o sugerencia, aquí estamos para darte un empujoncito. ¡Ánimos! ;-)
Saluditos!. .... ...(http://st.forocoches.com/foro/images/smilies/simba1.gif)
El tema de los índices ya lo he cambiado y en los dos arrays ya que en el segundo nunca van a salir palabras más largas que las primeras y lo deje así:
char capitulo[5][7] = {"pincel", "cinc", "cincel", "pipa", "papel"};
char cap[5][7];
Otro punto era la duda que tenía yo para mostrar cada palabra en una linea diferente con un for y veo que a un array bidimensional se le puede tratar solamente con un indice, como me muestras aqui:
for (i = 0; i<5; i++)
printf("%s ---->%s\n",capitulo1[i],cap1[i]);
Citar* En el caso de arrys de cadenas mejor que pensar en filas y columnas, algo típico en laos arrayas bidimensionales numéricos aunque en sí no esté mal, es pensar en posición de la cadenay caracter de dicha cadena.
Lo tendré en cuenta de aqui en adelante.
Citar* En los for se te fue la olla al poner fil=0 y col=0 cuando los índices son i y j, por lo que será i=0 y j=0.
Se me olvidó cambiarlo en todas las partes del programa, pero mejor lo dejo con i y j.
En el segundo código que me das no entiendo porque divides la longitud total de la palabra entre 2:
longitud=strlen(capitulo1[i])/2;
Edito: Vale ya lo entendí, en vez de restar 3 carcteres lo divides en 2 para que nunca quede una letras sola. En este mismo código declaras la variable longi, pero no veo que uso tiene.
Saludos.
Cita de: Caster en 19 Mayo 2013, 15:06 PM En este mismo código declaras la variable longi, pero no veo que uso tiene.
Ninguna utilidad, fue una variante que intenté, pero al final no me hizo falta usarla :-)
Ya he reeditado el post anterior y la he eliminado. Bien observado, aunque no hace mal sobra del código.
Saluditos!. .... ..(http://smilies-gifs.com/emoticonos-grandes/21grandes.gif)
Quería probar el código pero estoy volviendo a tener problemas con el compilador del Qt Creator, ya cree un posts aparte con esto y lo había resuelto pero vuelve a fallar, a ver si doy con la solución y lo pruebo.
Saludos
Cita de: Caster en 19 Mayo 2013, 15:45 PM
Quería probar el código pero estoy volviendo a tener problemas con el compilador del Qt Creator, ya cree un posts aparte con esto y lo había resuelto pero vuelve a fallar, a ver si doy con la solución y lo pruebo.
¿No usas Code:Blocks?.
Pruébalo y seguro que te encantará, con sus ventanitas y múltiples pestañas, su opción para C11 su ....... vamos no digo que dejes de usar el Qt Creator pero no te cuesta nada probar "don Code:Blocks" .
Saluditos!. ... ..(http://i1280.photobucket.com/albums/a497/leosansan/leosan1/15_zpsaac9030f.gif)
Bueno, ahora que tengo tiempo, retomo otra vez este problema, a día de hoy tengo este código:
#include <stdio.h>
#include <string.h>
int main(){
int i,j,longitud;
char capitulo1[5][11] = {"pincel", "cinc", "cinceles", "pipa", "termometro"};
char cap1[5][6]={0};
for (i= 0; i<5; i++){
longitud=strlen(capitulo1[i])/2;
for (j = 0;j<longitud; j++)
cap1[i][j] = capitulo1[i][j];
}
for (i = 0; i<5; i++)
printf("%s ---->%s\n",capitulo1[i],cap1[i]);
return 0;
}
Funciona, pero no del todo bien, porque lo que hace es mostrar la mitad de la palabra, y en el problema pide un "identificador" para cada palabra y no siempre es la mitad, en algunas es más largo y en otras más corto, lo que yo quería hacer es que haga eso con cualquier palabra introducida, pero no se me ocurre porque puede coger letras del principio, del final, por el medio... y no tengo ni la más mínima idea de como hacer.
Saludos
No hay nada peor que un problema no bien definido. En principio, lo que originó este tema, sólo habla de identificadores pero deja abierta la puerta a interpretaciones y eso es no estar bien definido el problema.
Una opción sería incluir además de las primeras letras un símbolo para las que no aparecen e incluir asimismo las finales. Por ejemplo:
pincel ---->pin-el
cinco ---->ci--o
cinceles ---->cinc--es
pipa ---->pi-a
termometro ---->termo---ro
Pero para gustos colores, es el problema de un ejercicio no bien definido, insisto.
#include <stdio.h>
#include <string.h>
int main(){
int i,j,longitud;
char capitulo1[5][11] = {"pincel", "cinco", "cinceles", "pipa", "termometro"};
char cap1[5][11]={0};
for (i= 0; i<5; i++)
{
longitud=strlen(capitulo1[i]);
for (j = 0;j<longitud/2; j++)
cap1[i][j] = capitulo1[i][j];
if (longitud<=5)
{
for (j = longitud/2;j<longitud-1; j++)
cap1[i][j] = '-';
cap1[i][longitud-1] =capitulo1[i][longitud-1] ;
}
else if (longitud>=6)
{
for (j = longitud/2;j<longitud-2; j++)
cap1[i][j] = '-';
cap1[i][longitud-2] =capitulo1[i][longitud-2] ;
cap1[i][longitud-1] =capitulo1[i][longitud-1] ;
}
printf("%s ---->%s\n",capitulo1[i],cap1[i]);
}
return 0;
}
Saluditos!
(http://st.forocoches.com/foro/images/smilies/aaaaa.gif)