Java - Ayuda en Recursividad

 
Vista:
sin imagen de perfil
Val: 5
Ha disminuido su posición en 99 puestos en Java (en relación al último mes)
Gráfica de Java

Ayuda en Recursividad

Publicado por arnau (3 intervenciones) el 12/06/2020 10:37:13
Buenos días, tengo un ejercicio que se me resiste, y no lo consigo sacar, este es el enunciado.


(Tenemos un String inicializado en la declaración por caracteres del alfabeto y dígitos del 0..9

Usando un algoritmo recursivo copiará el primer string en otro sustituyendo los dígitos por su correspondiente en caracteres.)

Por ejemplo: abs4tr6 sería convertido en abscuatrotrseis.
Nos ayuda con este código diciendo que nos puede ayudar a empezar.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class numerator {
    public static int preguntame_si_soy_blanco(char caracter_objetivo)
    {
        if (caracter_objetivo == ' ')
            return 1;
                else
            return 0;
    }
public static int calcular_blancos(String cad)
       {
    if (cad.charAt(0)=='.')
    return(0);
    else
        return (preguntame_si_soy_blanco(cad.charAt(0))+ calcular_blancos (cad.substring(1, cad.length())));
 
       }
        public static void main(String[] args) {
        String cadena = "En la sección de la lista de eventos del panel de simulación.";
        System.out.println("Hay "+ calcular_blancos(cadena)+ " blancos");
    }
 
}
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder
Imágen de perfil de Rodrigo
Val: 2.041
Plata
Ha mantenido su posición en Java (en relación al último mes)
Gráfica de Java

Ayuda en Recursividad

Publicado por Rodrigo (623 intervenciones) el 12/06/2020 17:32:15
- Cambia el tipo de retorno de la funcion preguntame a string.
-- Haz la logica para cada digito , si es '1' retornar 'uno', si es '2', retornar 'dos', etc.

- Cambia el tipo de retorno de la funcion calcular_blancos a string.
-- 2 casos ahi: el caracter no es un numero -> retornar un string que sea solo el digito que chequeas, o es un numero, en ese caso parece que puedes usar la misma expresion

- Renombra las funciones para que calce con lo que hacen
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil
Val: 19
Ha disminuido su posición en 79 puestos en Java (en relación al último mes)
Gráfica de Java

Ayuda en Recursividad

Publicado por isaac (6 intervenciones) el 13/06/2020 08:24:10
Se me ocurre que puede apoyarse en los métodos String.indexOf y String.replace(CharSequence target, CharSequence replacement)

puede ser algo similar (lo dejo para que lo mejore) a lo siguiente

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public static void main(String[] args) {
    System.out.println(cambiarcadena("0123456789", 0));
}
 
public static String cambiarcadena(String cadena, int numero){
    if(numero == 0){
        cadena = cambiarcadena(cadena.replace(String.valueOf(numero), "cero"), numero + 1);
    }else if(numero == 1){
        cadena = cambiarcadena(cadena.replace(String.valueOf(numero), "uno"), numero + 1);
    }else if(numero == 2){
        cadena = cambiarcadena(cadena.replace(String.valueOf(numero), "dos"), numero + 1);
    }else if(numero == 3){
        cadena = cambiarcadena(cadena.replace(String.valueOf(numero), "tres"), numero + 1);
    }else if(numero == 4){
        cadena = cambiarcadena(cadena.replace(String.valueOf(numero), "cuatro"), numero + 1);
    }else if(numero == 5){
        cadena = cambiarcadena(cadena.replace(String.valueOf(numero), "cinco"), numero + 1);
    }else if(numero == 6){
        cadena = cambiarcadena(cadena.replace(String.valueOf(numero), "seis"), numero + 1);
    }else if(numero == 7){
        cadena = cambiarcadena(cadena.replace(String.valueOf(numero), "siete"), numero + 1);
    }else if(numero == 8){
        cadena = cambiarcadena(cadena.replace(String.valueOf(numero), "ocho"), numero + 1);
    }else if(numero == 9){
        cadena = cambiarcadena(cadena.replace(String.valueOf(numero), "nueve"), numero + 1);
    }
 
    return cadena;
 
}

No es el mejor código pero funciona

aca la salida

1
2
3
run:
cerounodostrescuatrocincoseissieteochonueve
BUILD SUCCESSFUL (total time: 0 seconds)
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
Imágen de perfil de Sandro
Val: 392
Bronce
Ha mantenido su posición en Java (en relación al último mes)
Gráfica de Java

Ayuda en Recursividad

Publicado por Sandro (166 intervenciones) el 13/06/2020 16:55:26
por que darle la comida molida en la boca, que busque y muerda.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
Imágen de perfil de Kabuto
Val: 3.428
Oro
Ha mantenido su posición en Java (en relación al último mes)
Gráfica de Java

Ayuda en Recursividad

Publicado por Kabuto (1381 intervenciones) el 13/06/2020 20:01:14
Hola.
Tu código parece funcionar, pero no del todo.
Es decir, convierte la cadena correctamente. Y usa recursividad, pero en realidad no es la recursividad quién está convirtiendo la cadena. Al menos no en parte.

Llevo un rato mirando tu código, lo de usar el método replace() me tenía muy escamado.., por su forma de funcionar...

Y me ha dado por añadir a tu código un contador. Este contador cuenta (perdón por la redundancia) las veces que se itera tu método recursivo.
Es decir, cuantas veces se llama a sí mismo para lograr conseguir la tarea.
Y da un resultado muy curioso:
Fíjate, si le pasamos una cadena de un solo número, por ejemplo "0", da este resultado en pantalla:
1
2
3
4
Cadena a convertir: 0
Resultado de cambiarcadena()
cero
Iteraciones: 11
¡¡Se repite 11 veces para convertir un solo número!!

Y si le pasamos dos números:
1
2
3
4
Cadena a convertir: 01
Resultado de cambiarcadena()
cerouno
Iteraciones: 11
¡¡También 11 veces!!

Y si le pasamos 10 números:
1
2
3
4
Cadena a convertir: 0123456789
Resultado de cambiarcadena()
cerounodostrescuatrocincoseissieteochonueve
Iteraciones: 11

Lo mismo, ¿probamos con 30?
1
2
3
4
Cadena a convertir: 012345678901234567890123456789
Resultado de cambiarcadena()
cerounodostrescuatrocincoseissieteochonuevecerounodostrescuatrocincoseissieteochonuevecerounodostrescuatrocincoseissieteochonueve
Iteraciones: 11
¡¡También 11 veces!!

Da igual la cantidad de números que pongamos, siempre se itera 11 veces.
Sinceramente, no se explicar que mecánica está siguiendo tu método, pero lo que está claro es que la recursividad no está funcionando como debería.
Y la verdad es que me fascina
La cadena se está transformando, es cierto, pero me temo que es más gracias al método replace() que no a la recursividad que se le ha programado.

Si solo le pasamos 1 número, se ha de iterar 1 vez.
Y si le pasamos 30 números, pues se ha de iterar 30 veces.

He escrito yo otro método, donde hago uso del método subString().
Lo que hago es coger el primer carácter de la cadena con subString(0, 1).
Lo meto en un switch y evalúo si es "0", "1", etc...
En cada caso, retorno el String correspondiente "cero", "uno",... concatenandole una llamada recursiva a este método en el que le paso de nuevo la cadena, pero a partir del segundo carácter con subString(1)
Es decir, para cada llamada recursiva elimino el carácter que ya he evaluado.

Por tanto la cadena va perdiendo longitud en cada iteración, así que antes de hacer todo este proceso, siempre pregunto si la longitud de la cadena es 0, en cuyo caso retorno un String vacio sin ninguna llamada recursiva. Porque es entonces cuando la recursividad ha de terminar.

Le he añadido también un contador, así en el código podemos ver cuantas veces se itera este método y comparar con el tuyo.

Mira, este es el código, donde probaremos ambos métodos, cada uno con su contador:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
public class Convertidor {
 
	//Para contar las iteraciones de cada método recursivo
	static int cont1 = 0;
	static int cont2 = 0;
 
	public static void main(String[] args) {
		String cadena = "0";
		System.out.println("Cadena a convertir: " + cadena);
 
		System.out.println("\nResultado de cambiarcadena()");
		System.out.println(cambiarcadena(cadena, 0));
		System.out.println("Iteraciones: " + cont1);
		System.out.println("\nResultado de cambiarCadena2()");
		System.out.println(cambiarCadena2(cadena));
		System.out.println("Iteraciones: " + cont2);
	}
 
	public static String cambiarCadena2(String cadena) {
		if (cadena.length() == 0) //Ya no quedan caracteres en la cadena
			return ""; //Esto pone fin a las llamadas recursivas
		else {
			cont2++; //Contamos iteracion
			switch(cadena.substring(0, 1)) {
			case "0":
				return "cero" + cambiarCadena2(cadena.substring(1));
			case "1":
				return "uno" + cambiarCadena2(cadena.substring(1));
			case "2":
				return "dos" + cambiarCadena2(cadena.substring(1));
			case "3":
				return "tres" + cambiarCadena2(cadena.substring(1));
			case "4":
				return "cuatro" + cambiarCadena2(cadena.substring(1));
			case "5":
				return "cinco" + cambiarCadena2(cadena.substring(1));
			case "6":
				return "seis" + cambiarCadena2(cadena.substring(1));
			case "7":
				return "siete" + cambiarCadena2(cadena.substring(1));
			case "8":
				return "ocho" + cambiarCadena2(cadena.substring(1));
			case "9":
				return "nueve" + cambiarCadena2(cadena.substring(1));
			default:
				return cadena.substring(0, 1) + cambiarCadena2(cadena.substring(1));
			}
		}
	}
 
	public static String cambiarcadena(String cadena, int numero){
		if(numero == 0){
			cadena = cambiarcadena(cadena.replace(String.valueOf(numero), "cero"), numero + 1);
		}else if(numero == 1){
			cadena = cambiarcadena(cadena.replace(String.valueOf(numero), "uno"), numero + 1);
		}else if(numero == 2){
			cadena = cambiarcadena(cadena.replace(String.valueOf(numero), "dos"), numero + 1);
		}else if(numero == 3){
			cadena = cambiarcadena(cadena.replace(String.valueOf(numero), "tres"), numero + 1);
		}else if(numero == 4){
			cadena = cambiarcadena(cadena.replace(String.valueOf(numero), "cuatro"), numero + 1);
		}else if(numero == 5){
			cadena = cambiarcadena(cadena.replace(String.valueOf(numero), "cinco"), numero + 1);
		}else if(numero == 6){
			cadena = cambiarcadena(cadena.replace(String.valueOf(numero), "seis"), numero + 1);
		}else if(numero == 7){
			cadena = cambiarcadena(cadena.replace(String.valueOf(numero), "siete"), numero + 1);
		}else if(numero == 8){
			cadena = cambiarcadena(cadena.replace(String.valueOf(numero), "ocho"), numero + 1);
		}else if(numero == 9){
			cadena = cambiarcadena(cadena.replace(String.valueOf(numero), "nueve"), numero + 1);
		}
		cont1++; //Contamos iteracion
		return cadena;
 
	}
 
}


Si probamos con un solo número:
1
2
3
4
5
6
7
8
9
Cadena a convertir: 0
 
Resultado de cambiarcadena()
cero
Iteraciones: 11
 
Resultado de cambiarCadena2()
cero
Iteraciones: 1

Vemos que el nuevo método solo se itera 1 vez.
Con dos números:
1
2
3
4
5
6
7
8
9
Cadena a convertir: 01
 
Resultado de cambiarcadena()
cerouno
Iteraciones: 11
 
Resultado de cambiarCadena2()
cerouno
Iteraciones: 2

Pues dos iteraciones, que es lo esperable.
Si directamente pasamos a 30 números:
1
2
3
4
5
6
7
8
9
Cadena a convertir: 012345678901234567890123456789
 
Resultado de cambiarcadena()
cerounodostrescuatrocincoseissieteochonuevecerounodostrescuatrocincoseissieteochonuevecerounodostrescuatrocincoseissieteochonueve
Iteraciones: 11
 
Resultado de cambiarCadena2()
cerounodostrescuatrocincoseissieteochonuevecerounodostrescuatrocincoseissieteochonuevecerounodostrescuatrocincoseissieteochonueve
Iteraciones: 30

Pues 30 iteraciones.
Queda patente que la recursividad aquí si que está funcionando como es debido.


En cualquier caso, aunque tu método no sea lo que se esperaba, oye, está muy bien haber dado con una solución, aunque no sea la correcta.
Es genial que hayas intentado y probado cosas hasta lograr algo por tu cuenta, cosa que no hacen la mayoría.

Ha pasado que tu método "engaña" je je, porque hace la conversión correctamente y entonces parece que es una solución a lo que se pide.
Pero no es así.

E insisto que me sigue teniendo fascinado, eso de que se itere siempre 11 veces, le pases 1 número o le pases 500..., tengo que seguir estudiándolo hasta entender su mecánica ja ja..

Pregunta y repregunta si algo no te ha quedado claro del método que he escrito.
Un saludo.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
Imágen de perfil de Rodrigo
Val: 2.041
Plata
Ha mantenido su posición en Java (en relación al último mes)
Gráfica de Java

Ayuda en Recursividad

Publicado por Rodrigo (623 intervenciones) el 13/06/2020 21:16:54
No estas contando que replace itera al interior del string para hacer los reemplazos. En 1 iteracion haces varios reemplazos (si es que se hacen, pero aun asi se requiere recorrer el string para realizar la operacion)
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Ayuda en Recursividad

Publicado por Tom (1831 intervenciones) el 13/06/2020 21:17:06
Esta es la solución propuesta por isaac (válida en mi opinión, se trata de resolver un ejercicio de aprendizaje, no un problema real):

1
2
3
4
5
6
7
8
9
10
11
12
13
public class Recur {
	static String texts[] = {"cero", "uno", "dos", "tres", "cuatro", "cinco", "seis", "siete", "ocho", "nueve"};
	/* */
	static String replace(String str, int val) {
		return (val < 10) ? replace(str.replace(String.valueOf(val), texts[val]), val + 1) : str;
	}
	/* */
	public static void main(String args[]) {
		String test = new String("9,8,7,6,5,4,3,2,1,0");
		System.out.println(test);
		System.out.println(replace(test, 0));
	}
}

Y esta sería el código complicado para "ver" la recursividad:

1
2
3
4
5
6
7
/* */
	static String replace(String str, int val) {
		System.out.printf("Enter with val %d\n", val);
		String nstr = (val < 10) ? replace(str.replace(String.valueOf(val), texts[val]), val + 1) : str;
		System.out.printf("Exit of val %d\n", val);
		return nstr;
	}
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
1
Comentar
sin imagen de perfil
Val: 19
Ha disminuido su posición en 79 puestos en Java (en relación al último mes)
Gráfica de Java

Ayuda en Recursividad

Publicado por isaac (6 intervenciones) el 13/06/2020 23:08:46
La razón por la que siempre se hacen 11 recursividades, es la siguiente: al tener una cadena de caracteres de diferentes tipos, no podemos determinar cuantos de estos caracteres son dígitos, de forma tal que tendría que validar carácter por carácter si es dígito o no, teniendo en cuenta que los dígito son solo 10 (1, 2,3, 4, 5, 6, 7, 8, 9), en cierta forma y dado el desconocimiento de cuantos dígitos y cuantas repeticiones del mismo hay en la cadena y que solo son 10 dígitos, una forma es mandar a reemplazarlos todos existan o no existan, de esta forma la recursividad se hace 10 veces y una adicional para romperla, por eso siempre es 11. En el ejemplo que coloca donde se hacen 11 iteraciones para un solo número puede que no sea óptimo, pero si ese número esta 50 veces, se hacen 50 reemplazos pero solo en una iteración de la recursividad, las otras 10 no hacen ningún cambio y de ahí que el comentario de @Rodrigo es totalmente valido, el método String.replace hace iteraciones internas, pero el ya las sabe hacer y no voy a inventar la rueda.

El código que coloque fue para dar una idea de "como podría ser", y en el mismo coloque el comentario de "hay que mejorarlo". La respuesta de @Tom me parece una muy buena mejora a lo que intente decir.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Ayuda en Recursividad

Publicado por Costero (148 intervenciones) el 15/06/2020 16:32:36
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
import java.util.HashMap;
import java.util.Map;
 
public class NumeratorRecursion {
 
    private static Map<Character, String> charToString;
    static {
        charToString = new HashMap<>();
        charToString.put('0', "Zero");
        charToString.put('1', "Uno");
        charToString.put('2', "Dos");
        charToString.put('3', "Tres");
        charToString.put('4', "Cuatro");
        charToString.put('5', "Cinco");
        charToString.put('6', "Seis");
        charToString.put('7', "Siete");
        charToString.put('8', "Ocho");
        charToString.put('9', "Nueve");
    }
 
 
    public static String quitaNumero(char input) {
        StringBuilder sb = new StringBuilder();
 
        if (Character.isDigit(input)) {
            sb.append(charToString.get(input));
        } else {
            sb.append(input);
        }
        return sb.toString();
    }
 
    public static String processarNumero(String cad) {
        if (cad.charAt(0) == '.')
            return "";
        else
            return (quitaNumero(cad.charAt(0)) + processarNumero(cad.substring(1)));
 
    }
 
 
    public static void main(String[] args) {
        String cadena = "En la sec6ión de la lista de eve3tos del pan4l de simul9ción.";
        System.out.println("[" + processarNumero(cadena) + "]");
    }
}
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar