Por Nacho Cabanes
Nivel de dificultad aproximado (1 a 5): 2
Una sopa de letras consiste de un arreglo rectangular en cada una de cuyas posiciones se encuentra una letra minúscula. Además, se tiene una lista de palabras (formadas cada una exclusivamente por letras minúsculas) que se deben de buscar en el arreglo. Una palabra puede aparecer en línea recta en el arreglo en ocho posibles direcciones comenanzdo desde su primer letra: hacia arriba, hacia abajo, hacia la derecha, hacia la izquierda y en las cuatro direcciones diagonales. Además, una palabra puede aparecer en más de un lugar.
PROBLEMA
Deberás escribir un programa que reciba como entrada las dimensiones del arreglo rectangular, las letras que aparecen en el mismo, el tamaño de la lista y la lista de palabras a buscar y que determine cuántas veces aparece cada una de estas palabras en el arreglo.
ENTRADA
Tu programa deberá leer del teclado de la PC los siguientes datos
SALIDA
Tu programa deberá escribir en la pantalla de la computadora K líneas y en cada una de ellas debe aparecer la cantidad X1 de veces que aparece la palabra P1
(Asegúrate de que has leído las preguntas frecuentes antes de plantear tu solución)
ENTRADA 2 3 aal ala 2 al ala SALIDA 6 2
// Ejemplo de solución para el reto 016 // Sopa de letras, por Luis_Angel // Por Luis_Angel, 21-jun-2014 // Nota del recopilador: la solución no es totalmente correcta: // Pide una palabra, en vez de leer desde la entrada estándar un contador y una serie de palabras #include "iostream" using namespace std; int i,j,nf,nc; int main() { string pal; char sopa[100][100],palabra[100]; int i,j,k,pf,pc,num_tot; bool esta; cin>>nf; // Filas cin>>nc; // Columnas for(i=0;i<nf;i++) for(j=0;j<nc;j++) cin>>sopa[i][j]; /*cout<<"La sopa es\n"; for(i=0;i<nf;i++) {cout<<"\n\n"; for(j=0;j<nc;j++) cout<<sopa[i][j]<<"\t"; }*/ cout<<"\nIngrese una palabra para buscar: ";cin>>pal; for(i=0;i<pal.length();i++) palabra[i]=pal.at(i); num_tot=0; esta=false; for(i=0;i<nf;i++) for(j=0;j<nc;j++) if(palabra[0]==sopa[i][j]) { for(k=1;k<pal.length();k++) { if(sopa[i][j+k]==palabra[k] && (j+k)<nc) esta=true; else {esta=false; break; } } if(esta==true) num_tot++; } for(i=0;i<nf;i++) for(j=0;j<nc;j++) if(palabra[0]==sopa[i][j]) { for(k=1;k<pal.length();k++) { if(sopa[i][j-k]==palabra[k] && (j-k)>=0) esta=true; else {esta=false; break; } } if(esta==true) num_tot++; } for(i=0;i<nf;i++) for(j=0;j<nc;j++) if(palabra[0]==sopa[i][j]) { for(k=1;k<pal.length();k++) { if(sopa[i+k][j]==palabra[k] && (i+k)<nf) esta=true; else {esta=false; break; } } if(esta==true) num_tot++; } for(i=0;i<nf;i++) for(j=0;j<nc;j++) if(palabra[0]==sopa[i][j]) { for(k=1;k<pal.length();k++) { if(sopa[i-k][j]==palabra[k] && (i-k)>=0) esta=true; else {esta=false; break; } } if(esta==true) num_tot++; } for(i=0;i<nf;i++) for(j=0;j<nc;j++) if(palabra[0]==sopa[i][j]) { for(k=1;k<pal.length();k++) { if(sopa[i+k][j+k]==palabra[k] && (i+k)<nf && (j+k)<nc) esta=true; else {esta=false; break; } } if(esta==true) num_tot++; } for(i=0;i<nf;i++) for(j=0;j<nc;j++) if(palabra[0]==sopa[i][j]) { for(k=1;k<pal.length();k++) { if(sopa[i-k][j-k]==palabra[k] && (i-k)>=0 && (j-k)>=0) esta=true; else {esta=false; break; } } if(esta==true) num_tot++; } cout << num_tot<< endl; return 0; }
// Ejemplo de solución para el reto 016 // Sopa de letras, por Caranim // Por Caranim, 08-jul-2014 // Nota del recopilador: // La lógica es buena, pero no es una solución totalmente válida, // Por mostrar información adicional en pantalla // Y emplear colores y Readkey using System; using System.Collections.Generic; using System.Text; using System.IO; /* ------------------------------------------------------------------------------------------------------------------------------------------* Reto: 16 ( Sopa de letras ). *Ejemplo de entrada propuesto originalmente en la especificación del Reto. ENTRADA 2 3 aal ala 2 al ala SALIDA 6 2 ________________________________________________________________________________________ Ejemplo para un fichero de entrada. Pegar todas las líneas en un archivo de texto plano con nombre "MatrizLetras.txt" para poder ejecutar la solución. 15 15 foktaicergniica grtcuyagtreuniv rtaathurdtcmcbf einntcflouheior cliacivomprsaba iytdyiitageuron ffpasiatdbfwcnc rawtkilvhsbcaai axwsfdaudqdxnhn nzxibdaiutvaajd cekmaeyiefdgdei irondssrlakbaaa tcayrurnoruegai sgrecianoruegaa agailatitaliatr 7 italia grecia canada india peru francia noruega */ namespace Sopa_de_Letras { class Program { static string[] sopa_filas; static ListaBuscar[] palabras_objetivo; static void Main(string[] args) { bool tmpbool; Console.BackgroundColor = ConsoleColor.White; Console.ForegroundColor = ConsoleColor.DarkGray; Console.Clear(); // Proceso para cargar datos. El enunciado pide que sea via teclado, pero de esta manera es más rápido testar el programa. if (File.Exists("C:\\Ejercicios programacion\\SopaLetras\\Sopa de Letras\\MatrizLetras.txt")) { tmpbool = Cargar_Datos_Fichero("C:\\Ejercicios programacion\\SopaLetras\\Sopa de Letras\\MatrizLetras.txt"); } else{ tmpbool = Cargar_Datos_Teclado(); } if (tmpbool) { // Proceso de búsqueda. foreach (ListaBuscar objetivos in palabras_objetivo) { // Buscar para cada uno de los 8 posibles sentidos. for (int fila_actual = 0; fila_actual < sopa_filas.Length; fila_actual++) { for (int col_actual = 0; col_actual < sopa_filas[fila_actual].Length; col_actual++) { for (int incx = -1; incx < 2; incx++) { for (int incy = -1; incy < 2; incy++) { if (!(incx == 0 && incy == 0)) { if (buscar_palabra(objetivos.palabra(), fila_actual, col_actual, incx, incy)) { objetivos.encontrada(); } } } } } } } // Proceso de muestra de resultados. foreach (ListaBuscar objetivos in palabras_objetivo) { Console.WriteLine("{0} --> {1} Veces.", objetivos.palabra(), objetivos.veces()); } } else { Console.WriteLine("El proceso de carga de datos ha fallado."); } Console.ReadKey(); // Pausa para que la pantalla no se cierre al terminar el proceso y podamos ver los resultados. } static bool Cargar_Datos_Teclado() { // Primera línea de datos: Nº de filas y columnas de nuestra Sopa de letras. string linealeida; int filas, columnas; Console.WriteLine ("Introduce el número de FILAS y COLUMNAS de la Sopa de letras separados por un Espacio."); linealeida = Console.ReadLine(); filas = Convert.ToInt32(linealeida.Substring(0, linealeida.IndexOf(" "))); columnas = Convert.ToInt32(linealeida.Substring(linealeida.IndexOf(" "))); sopa_filas = new string[filas]; // Cargar los caracteres de la matriz. for (int indice = 0; indice < filas; indice++) { Console.WriteLine("Introduce la fila número {0} de la Sopa de Letras.", indice+1); linealeida = Console.ReadLine(); if (linealeida.Length < columnas) // Por si nos falta algún caracter en alguna de las líneas. { Console.WriteLine("La línea " + indice + " no tiene el número de caracteres necesarios."); } sopa_filas[indice] = linealeida.Substring(0,columnas); // Para que no tome más columnas de las debidas. } // Capturar el número de palabras a buscar y las palabras. Console.Clear(); Console.WriteLine("Introduce el número de palabras a buscar."); linealeida = Console.ReadLine(); palabras_objetivo = new ListaBuscar[Convert.ToInt32(linealeida)]; for (int indice = 0; indice < palabras_objetivo.Length; indice++) { Console.WriteLine("Escribe la palabra a buscar Num. {0}.", indice); linealeida = Console.ReadLine(); if (linealeida.Length < 2 ) { Console.WriteLine("No se admiten palabras de menos de dos caracteres.\n Se cancela el proceso."); Console.ReadKey(); // Para hacer una pausa y dar tiempo a leer el mensaje. return false; } palabras_objetivo[indice] = new ListaBuscar(linealeida); } return true; } static bool Cargar_Datos_Fichero(string nombrefichero) // Retorna "true" si la carga se ha producido sin problemas.Solo devuelve False si el fichero no existe o alguna de las palabras objetivo // tiene longitud inferior a 2 caracteres , pero realmentese pueden dar bastantes más casos que no están contemplados en esta solución. { StreamReader fich_datos; string linealeida; int filas, columnas; fich_datos = new StreamReader(nombrefichero); // Comprobar que el fichero exista. if (!System.IO.File.Exists(nombrefichero)) { Console.WriteLine("No existe el fichero " + nombrefichero); return false; } fich_datos = File.OpenText(nombrefichero); // Empezamos a leer el fichero y a cargar los valores necesarios. linealeida = fich_datos.ReadLine(); // Cargamos el número de filas y columnas que vamos a necesitar. filas = Convert.ToInt32(linealeida.Substring(0, linealeida.IndexOf(" "))); columnas = Convert.ToInt32(linealeida.Substring(linealeida.IndexOf(" "))); sopa_filas = new string[filas]; // Cargamos los caracteres de la matriz de la Sopa de Letras. for (int indice = 0; indice < filas; indice++) { linealeida = fich_datos.ReadLine(); if (linealeida.Length < columnas) // Por si nos falta algún caracter en alguna de las líneas. { Console.WriteLine("La línea " + indice + " no tiene el número de caracteres necesarios."); fich_datos.Close(); return false; } sopa_filas[indice] = linealeida.Substring(0,columnas); // Para que no tome más columnas de las debidas. } // Cargamos el número de palabras a buscar. linealeida = fich_datos.ReadLine(); palabras_objetivo = new ListaBuscar[Convert.ToInt32(linealeida)]; for (int indice = 0; indice < palabras_objetivo.Length; indice++) { linealeida = fich_datos.ReadLine(); if (linealeida.Length < 2 ) { Console.WriteLine("No se admiten palabras de menos de dos caracteres.\n Se cancela el proceso."); Console.ReadKey(); // Para hacer una pausa y dar tiempo a leer el mensaje. return false; } palabras_objetivo[indice] = new ListaBuscar(linealeida); } fich_datos.Close(); return true; } static bool buscar_palabra(string palabra, int xinicial, int yinicial, int inc_x, int inc_y) { bool retorno = false; bool seguir = true; int iteraciones = 0; while (seguir) { if (xinicial < 0 || yinicial < 0 || xinicial + 1 > sopa_filas.Length || yinicial + 1 > sopa_filas[0].Length) { seguir = false; } else { if (palabra.Substring(iteraciones, 1) == sopa_filas[xinicial].Substring(yinicial, 1)) { iteraciones++; xinicial += inc_x; yinicial += inc_y; if (iteraciones == palabra.Length ) // Hemos encontrado una coincidencia. { retorno = true; seguir = false; } } else { seguir = false; } } } return retorno; } } class ListaBuscar // Guarda las palabras y las veces que la hemos encontrado. { string _palabra; int _veces; public ListaBuscar(string palabra) { _palabra = palabra; _veces = 0; } public string veces() { return _veces.ToString().Trim(); } public string palabra() { return _palabra; } public int Longitud() { return _palabra.Length; } public void encontrada() { _veces++; } }