Recorrer y sustituir en matriz JAVA

Iniciado por Tonyskater, 1 Mayo 2017, 01:38 AM

0 Miembros y 2 Visitantes están viendo este tema.

Tonyskater

Hola buenas noches, primero que nada me presento, soy Tony estudiante de formación superior de desarrollo de aplicaciones web.

Tengo un pequeño problema, yo creo bastante simple pero que mi cabeza por algún motivo no procesa. El problema es el siguiente, estoy haciendo un ejercicio para hacer una sopa de letras, no funcional, me explico, no se va a acceder a ningún fichero diccionario ni nada parecido, simplemente interactuaremos con los resultados generados por nuestro propio código. Y realmente estoy atascado en el momento de buscar y sustituir valores en la matriz.

public static /*char[][]*/ int sustituir(char[][] m, String s) {
        int cont = 0;
        for (int i = 0; i < m.length; i++) {
            for (int j = 0; j < m[i].length; j++) {
                if(s.charAt(i)==m[i][j]){
                    cont++; //esto es simplemente para ver si llega a interpretar la condición
                }
            }
        }
        return cont;
    }
}

Esa función realmente debería devolver un vector de caracteres con los caracteres que le pase en el string sustituidos 1 única vez en toda la matriz. (Sí, el código aun está en ropa interior, pero no logro empezar bien...).

El problema creo que está en el condicional, ya que si le paso una cadena  con menor longitud que el vector saltará un OutOfBoundsException. No sé solucionarlo...
Cita de: Manual de mantenimiento de IBM"Todas las piezas deben unirse sin ser forzadas. Debe recordar que los componentes que está reensamblando fueron desmontados por usted, por lo que si no puede unirlos debe existir una razón. Pero sobre todo, no use un martillo"
Mi nombre es Tony y estoy aqui para aprender, pero si hay algo que pueda compartir con vosotros lo haré.

3n31ch

#1
No entiendo tu código ya que si bien el "char[][] m" puede ser tu sopa de letras y el "String s" puede ser la palabra que agregas... en ningún momento dices donde agregarla.

Entiendo que tu función es algo como esto:

Entradas: char[][] m (Sopa), String s (Palabra)
Proceso: Remplazar en la sopa de letras los espacios vacíos por las letras de la palabra agregada.
Salida: char[][] m (Sopa con las letras agregadas).

Y al menos yo no veo forma de conseguir esa salida con las entradas que me das. Por tanto,  que tal si agregamos tres entradas mas: int ix (Punto x inicial), int iy (Punto y inicial) y boolean isHorizontal (Para saber si tengo que agregar la palabra en horizontal o vertical).

Con estos tres parámetros mas podrás saber en donde empezar a agregar y hacia donde agregarlo.

Código (java) [Seleccionar]

public static void main(String[] args) {
       
       // ACA CREO MI SOPA Y LE PONGO LOS ESPACIOS EN BLANCO (Le asigno el mismo len para que sea cuadrado)
       int len = 20;
       char[][] sopa = new char[len][len];
       for (int i = 0; i < sopa.length; i++) {
           for (int j = 0; j < sopa[i].length; j++) {
               sopa[j][i] = ' '; // PONGO TODOS LOS ESPACIOS EN BLANCO
           }
       }
       // ACA TERMINO DE PONER LOS ESPACIOS EN BLANCO
       
       
       // AHORA IMPRIMIRE MI MATRIZ SOPA, PARA VER QUE ESTA SIN "NADA" DENTRO
       for (int i = 0; i < len; i++) {
           for (int j = 0; j < len; j++) {
               System.out.print("[" + sopa[j][i] + "]"); // Los volteo ya que la forma natural seria imprimir de cada "x" todos los "y" y quiero que sea de cada "y" los "x" como una pantalla
           }
           System.out.println("");
       }
       System.out.println("\n\n----------------\n\n"); // Este es un espacio para que no se me junte con la siguiente
       // TERMINE DE IMPRIMIRLO
       
       String palabra = "elhacker.net"; // AGREGARE ESTA PALABRA
       int x = 2; // EN X = 2
       int y = 4; // E Y = 4 -- RECUERDA QUE PARTEN EN 0
       boolean isHorizontal = false;
       
       // Ahora uso mi funcion:
       sopa = sustituir(sopa, palabra, x, y, isHorizontal);
       
       // AHORA IMPRIMIRE MI MATRIZ SOPA, PARA VER QUE FUNCIONO
       for (int i = 0; i < len; i++) {
           for (int j = 0; j < len; j++) {
               System.out.print("[" + sopa[j][i] + "]");
           }
           System.out.println("");
       }
       // TERMINE DE IMPRIMIRLO
       
   }
   
   public static char[][] sustituir(char[][] sopa, String palabra, int x, int y, boolean isHorizontal) {
       
       // VALIDO QUE SE PUEDA AGREGAR - QUE NO EXCEDA EL TAMAÑO MAXIMO DE LA MATRIZ, ESTO ES LO QUE TE PASA A TÍ... (EXACTO COMO TU DICES)
       if(isHorizontal) {
           if(sopa.length < x + palabra.length()) {
               System.out.println("NO SE PUEDE AGREGAR LA PALABRA");
               return sopa;
           }
       } else {
           if(sopa[x].length < y + palabra.length()) {
               System.out.println("NO SE PUEDE AGREGAR LA PALABRA");
               return sopa;
           }
       }
       // TERMINO DE VALIDAR
       // AHORA AGREGO
       if(isHorizontal) {
           for (int i = x; i < palabra.length() + x; i++) {
               sopa[i][y] = palabra.charAt(i - x);
           }
       } else {
           for (int i = y; i < palabra.length() + y; i++) {
               sopa[x][i] = palabra.charAt(i - y);
           }
       }
       return sopa;
   }


Normalmente no pondría todo el código, peor hoy me siento bondadoso (o malo, depende de como lo mires).

Suerte! (Cualquier cosa nos dices, seguro yo o alguien mas te responderá... me demore en responder ya que vi que no estaba en Java y quería esperar que lo cambiaran  :xD solo por joder.)

Tonyskater

#2
Cita de: 3n31ch en  1 Mayo 2017, 09:27 AM
No entiendo tu código ya que si bien el "char[][] m" puede ser tu sopa de letras y el "String s" puede ser la palabra que agregas... en ningún momento dices donde agregarla.

Entiendo que tu función es algo como esto:

Entradas: char[][] m (Sopa), String s (Palabra)
Proceso: Remplazar en la sopa de letras los espacios vacíos por las letras de la palabra agregada.
Salida: char[][] m (Sopa con las letras agregadas).

Y al menos yo no veo forma de conseguir esa salida con las entradas que me das. Por tanto,  que tal si agregamos tres entradas mas: int ix (Punto x inicial), int iy (Punto y inicial) y boolean isHorizontal (Para saber si tengo que agregar la palabra en horizontal o vertical).

Con estos tres parámetros mas podrás saber en donde empezar a agregar y hacia donde agregarlo.

Normalmente no pondría todo el código, peor hoy me siento bondadoso (o malo, depende de como lo mires).

Suerte! (Cualquier cosa nos dices, seguro yo o alguien mas te responderá... me demore en responder ya que vi que no estaba en Java y quería esperar que lo cambiaran  :xD solo por joder.)
Hola, gracias por responder.
Realmente no llega a ser una sopa de letras, digamos que tenemos una matriz de char generados aleatoriamente. Yo le introduzco una cadena, no necesariamente tiene que estar la cadena ordenada dentro de la matriz. Y mi función debería encontrar 1 coincidencia por cada elemento del String, y esa única coincidencia sustituirla por un [ * ] .

Dicho esto, solucioné el problema que había con el OutOfBoundsException con el siguiente public static char[][] sustituir(char[][] m, String s) {
       for (int a = 0; a < s.length(); a++) {
           for (int i = 0; i < m.length; i++) {
               for (int j = 0; j < m[i].length; j++) {
                   if (s.charAt(a) == m[i][j]) {
                       m[i][j]='*';
                   }
               }
           }
       }
       return m;

Ahora el problema está en que tengo que sustituir una única vez cada caracter de la matriz por cada caracter de la cadena. Es decir si tengo la matriz:

A B C D E F G
H I J K L M N
O P Q R S T U
A I P T R A Z
S Z A J K P N

Y tengo la cadena ABRS quedaría así:

* * C D E F G
H I J K L M N
O P Q * * T U
A I P T R A Z
S Z A J K P N

PD: Siento lo de donde puse el post, no estoy acostumbrado a postear en foros y no vi donde iba... Gracias!

Este es el codigo de mi programa:
public class Sustituir {

    public static void main(String[] args) {
        int dimension=demanarDimensio();
        char[][] vectorCuadro = genCuadro(dimension);
        char[][] sustituido;
        mostrarInstruccions();
        boolean continuar;
        do{
            mostrarSopaLletres(vectorCuadro);
            String palabra=pedirPalabra();
            sustituido = sustituir(vectorCuadro, palabra);
            System.out.println("----------------------------");
            mostrarSopaLletres(sustituido);
            continuar = preguntarContinuar();
        }while (calcularLletresQueQueden(vectorCuadro) > 1 && continuar);
        mostrarCredits();
    }
    public static void mostrarCredits() {
        System.out.println("Gracias por participar en la comprobación de funcionamiento de la sopa de letras de Antonio Gonzalez la Carrubba");
        System.out.println("Autor:");
        System.out.println("Antonio Gonzalez la Carrubba");
    }
    public static boolean preguntarContinuar(){
        Scanner entrada = new Scanner(System.in);
        System.out.println("Quieres continuar: ");
        String cont=entrada.next().toLowerCase();
        if(cont.equals("si")){
            return true;
        }else{
            return false;           
        }
    }
    public static boolean continuar(boolean continuar) {
        if (continuar) {
            return true;
        } else {
            return false;
        }
    }
    public static int calcularLletresQueQueden(char[][] tauler) {
        int cont = 0;
        for (int n = 0; n < tauler.length; n++) {
            for (int o = 0; o < tauler[n].length; o++) {
                if (tauler[n][o] != '*') {
                    cont++;
                }
            }
        }
        return cont;
    }
    public static int demanarDimensio() {
        Scanner entrada = new Scanner(System.in);
        System.out.println("Introduce dimension: ");
        int dimension=entrada.nextInt();
        return dimension;
    }
    public static void mostrarInstruccions() {
        System.out.println("Sopa de Letras v.1");
        System.out.println("Reglas del juego");
        System.out.println("Se mostrará un cuadro con letras desordenadas");
        System.out.println("con las cuales el jugador debera formar palabras hasta que se terminen las letras del tablero");
        System.out.println("Al final del juego se mostrará la puntuación obtenida.");
    }
    public static String pedirPalabra(){
        Scanner entrada = new Scanner(System.in);
        System.out.println("Introduce palabra: ");
        String palabra=entrada.next().toUpperCase();
        return palabra;
    }

    public static void mostrarSopaLletres(char[][] tauler) {
        for (int n = 0; n < tauler.length; n++) {
            for (int o = 0; o < tauler[n].length; o++) {
                System.out.printf("%2c", tauler[n][o]);
            }
            System.out.println();
        }
    }

    public static char[][] generarSopaLletres(int dimensio) {
        char[][] vectorGen = new char[dimensio][dimensio];
        for (int i = 0; i < dimensio; i++) {
            for (int j = 0; j < dimensio; j++) {
                vectorGen[i][j] = (char) (Math.random() * (90 - 65 + 1) + 65);
            }
        }
        return vectorGen;
    }

    public static char[][] genCuadro(int cantVal) {
        char[][] vectorGen = new char[cantVal][cantVal];
        for (int i = 0; i < cantVal; i++) {
            for (int j = 0; j < cantVal; j++) {
                vectorGen[i][j] = (char) (Math.random() * (90 - 65 + 1) + 65);
            }
        }
        return vectorGen;
    }

    public static char[][] sustituir(char[][] m, String s) {
        for (int a = 0; a < s.length(); a++) {
            for (int i = 0; i < m.length; i++) {
                for (int j = 0; j < m[i].length; j++) {
                    if (s.charAt(a) == m[i][j]) {
                        m[i][j]='*';
                    }
                }
            }
        }
        return m;
    }
    public static int calcularPuntuacio(String par, int queden, int dimensio) {
        int puntuacio;
        puntuacio = (par.length() * dimensio) - queden;
        return puntuacio;
    }
}
Cita de: Manual de mantenimiento de IBM"Todas las piezas deben unirse sin ser forzadas. Debe recordar que los componentes que está reensamblando fueron desmontados por usted, por lo que si no puede unirlos debe existir una razón. Pero sobre todo, no use un martillo"
Mi nombre es Tony y estoy aqui para aprender, pero si hay algo que pueda compartir con vosotros lo haré.

3n31ch

#3
Ahh, ok, ya entendí.

Solo aclárame una cosa: ¿Si yo ingresara "SABR" en vez de "ABRS" el resultado seria el mismo?


Por otro lado, cuando publiques código usa las etiquetas GeSHi con el lenguaje de tu Código. (Selecciona tu código y arriba, alado de una A roja, aparece un select. Ahí selecciona Java).


EDITO:

Como no me respondiste, esto es lo que creo que quieres:
Código (java) [Seleccionar]
public static char[][] sustituir(char[][] sopa, String palabra) {
        characterFor : for (int c = 0; c < palabra.length(); c++) {
            for (int i = 0; i < sopa.length; i++) {
                for (int j = 0; j < sopa[i].length; j++) {
                    if(sopa[i][j] == palabra.charAt(c)) {
                        sopa[i][j] = '*';
                        continue characterFor;
                    }
                }
            }
        }
        return sopa;
    }


Si no entiendes algo, dime.

Tonyskater

Cita de: 3n31ch en  1 Mayo 2017, 11:21 AM
Solo aclárame una cosa: ¿Si yo ingresara "SABR" en vez de "ABRS" el resultado seria el mismo?
EDITO:

Como no me respondiste, esto es lo que creo que quieres:
Código (java) [Seleccionar]
public static char[][] sustituir(char[][] sopa, String palabra) {
        characterFor : for (int c = 0; c < palabra.length(); c++) {
            for (int i = 0; i < sopa.length; i++) {
                for (int j = 0; j < sopa[i].length; j++) {
                    if(sopa[i][j] == palabra.charAt(c)) {
                        sopa[i][j] = '*';
                        continue characterFor;
                    }
                }
            }
        }
        return sopa;
    }


Si no entiendes algo, dime.
Ah vale, perfecto, gracias.
Es que soy nuevo con los foros jeje :P

Sí, el resultado sería el mismo.

La verdad me has solucionado perfectamente la duda.
Pero ahora tengo otra:
"characterFor :"
Qué es exactamente? y cómo se utiliza?

Por otro lado muchas gracias por la ayuda, aqui dejo el codigo final por si alguien tiene curiosidad o lo necesita
Código (java) [Seleccionar]
package Mezcladitos;
import java.util.*;
/**
*
* @author anton
*/
public class Sustituir {

    public static void main(String[] args) {
        int dimension=demanarDimensio();
        char[][] vectorCuadro = genCuadro(dimension);
        char[][] sustituido;
        mostrarInstruccions();
        boolean continuar;
        int puntuacio=0;
        do{
            mostrarSopaLletres(vectorCuadro);
            String palabra=pedirPalabra();
            sustituido = sustituir(vectorCuadro, palabra);
            puntuacio=puntuacio+calcularPuntuacio(palabra,queden(sustituido),vectorCuadro.length);
            System.out.println("Tu puntuacion obtenida es: "+puntuacio);
            System.out.println("----------------------------");
            mostrarSopaLletres(sustituido);
            continuar = preguntarContinuar();   
        }while (calcularLletresQueQueden(vectorCuadro) > 1 && continuar);
        mostrarCredits();
        System.out.println("Tu putnuación final es: "+puntuacio);
    }
    public static void mostrarCredits() {
        System.out.println("Gracias por participar en la comprobación de funcionamiento de la sopa de letras de Antonio Gonzalez la Carrubba");
        System.out.println("Autor:");
        System.out.println("Antonio Gonzalez la Carrubba");
    }
    public static boolean preguntarContinuar(){
        Scanner entrada = new Scanner(System.in);
        System.out.println("Quieres continuar: ");
        String cont=entrada.next().toLowerCase();
        if(cont.equals("si")){
            return true;
        }else{
            return false;           
        }
    }
    public static boolean continuar(boolean continuar) {
        if (continuar) {
            return true;
        } else {
            return false;
        }
    }
    public static int calcularLletresQueQueden(char[][] tauler) {
        int cont = 0;
        for (int n = 0; n < tauler.length; n++) {
            for (int o = 0; o < tauler[n].length; o++) {
                if (tauler[n][o] != '*') {
                    cont++;
                }
            }
        }
        return cont;
    }
    public static int demanarDimensio() {
        Scanner entrada = new Scanner(System.in);
        System.out.println("Introduce dimension: ");
        int dimension=entrada.nextInt();
        return dimension;
    }
    public static void mostrarInstruccions() {
        System.out.println("Sopa de Letras v.1");
        System.out.println("Reglas del juego");
        System.out.println("Se mostrará un cuadro con letras desordenadas");
        System.out.println("con las cuales el jugador debera formar palabras hasta que se terminen las letras del tablero");
        System.out.println("Al final del juego se mostrará la puntuación obtenida.");
    }
    public static String pedirPalabra(){
        Scanner entrada = new Scanner(System.in);
        System.out.println("Introduce palabra: ");
        String palabra=entrada.next().toUpperCase();
        return palabra;
    }

    public static void mostrarSopaLletres(char[][] tauler) {
        for (int n = 0; n < tauler.length; n++) {
            for (int o = 0; o < tauler[n].length; o++) {
                System.out.printf("%2c", tauler[n][o]);
            }
            System.out.println();
        }
    }

    public static char[][] generarSopaLletres(int dimensio) {
        char[][] vectorGen = new char[dimensio][dimensio];
        for (int i = 0; i < dimensio; i++) {
            for (int j = 0; j < dimensio; j++) {
                vectorGen[i][j] = (char) (Math.random() * (90 - 65 + 1) + 65);
            }
        }
        return vectorGen;
    }

    public static char[][] genCuadro(int cantVal) {
        char[][] vectorGen = new char[cantVal][cantVal];
        for (int i = 0; i < cantVal; i++) {
            for (int j = 0; j < cantVal; j++) {
                vectorGen[i][j] = (char) (Math.random() * (90 - 65 + 1) + 65);
            }
        }
        return vectorGen;
    }
    public static char[][] sustituir(char[][] sopa, String palabra) {
        characterFor : for (int c = 0; c < palabra.length(); c++) {
            for (int i = 0; i < sopa.length; i++) {
                for (int j = 0; j < sopa[i].length; j++) {
                    if(sopa[i][j] == palabra.charAt(c)) {
                        sopa[i][j] = '*';
                        continue characterFor;
                    }
                }
            }
        }
        return sopa;
    }
//    Fórmula = longitud de la paraula multiplicat per (la quantitat total de
//     * lletres del tauler - les que queden)
    public static int calcularPuntuacio(String par, int queden, int dimensio) {
        int puntuacio;
        puntuacio = (par.length() * (dimensio - queden));
        return -puntuacio;
    }
    public static int queden(char [][] sopa){
        int queden=0;
        for (int i = 0; i < sopa.length; i++) {
                for (int j = 0; j < sopa[i].length; j++) {
                    if(sopa[i][j] != '*'){
                        queden++;
                    }
                }
            }
        return queden;
    }
}
Cita de: Manual de mantenimiento de IBM"Todas las piezas deben unirse sin ser forzadas. Debe recordar que los componentes que está reensamblando fueron desmontados por usted, por lo que si no puede unirlos debe existir una razón. Pero sobre todo, no use un martillo"
Mi nombre es Tony y estoy aqui para aprender, pero si hay algo que pueda compartir con vosotros lo haré.

3n31ch

characterFor

Es el nombre que le puse a ese ciclo. Es como una etiqueta, para referirme a ese ciclo en un futuro (tengo entendido que no es muy buena practica hacerlo de esta forma, pero es fácil de implementar).

Por tanto cuando yo abajo pongo: continue characterFor, le estoy diciendo que termine de hacer lo que esta haciendo y que continue con la siguiente iteracion del ciclo llamado de esa forma.

Código (java) [Seleccionar]

nombreCiclo : for(int i = 0;i<10; i++) {
       
}

Tonyskater

Cita de: 3n31ch en  1 Mayo 2017, 13:55 PM
characterFor

Es el nombre que le puse a ese ciclo. Es como una etiqueta, para referirme a ese ciclo en un futuro (tengo entendido que no es muy buena practica hacerlo de esta forma, pero es fácil de implementar).

Por tanto cuando yo abajo pongo: continue characterFor, le estoy diciendo que termine de hacer lo que esta haciendo y que continue con la siguiente iteracion del ciclo llamado de esa forma.

Código (java) [Seleccionar]

nombreCiclo : for(int i = 0;i<10; i++) {
       
}


Ya entiendo, pues muchas gracias por tu ayuda compañero! He aprendido mucho.

PD: Cómo se cierra un tema? Aquí sigo con mis novatadas :P
Cita de: Manual de mantenimiento de IBM"Todas las piezas deben unirse sin ser forzadas. Debe recordar que los componentes que está reensamblando fueron desmontados por usted, por lo que si no puede unirlos debe existir una razón. Pero sobre todo, no use un martillo"
Mi nombre es Tony y estoy aqui para aprender, pero si hay algo que pueda compartir con vosotros lo haré.

3n31ch

Tampoco me hago mucho a la idea. Pero creo que en la esquina superior izquierda del mensaje que soluciono tu duda aparece un "ticket" o algo así (aunque creo que en todos los mensajes aparece).

:-X :-X :-X