Java - Devolver eliminando valores duplicados

 
Vista:
sin imagen de perfil

Devolver eliminando valores duplicados

Publicado por Pedro (7 intervenciones) el 19/09/2022 15:05:27
Buenas.

Me han mandado un ejercicio en el que tengo que devolver los valores de un array quitando los duplicados, y haciendo que los valores devueltos empiecen por mayuscula. No se ni como empezar, según el profesor es un ejercicio báscio, pero solo he visto en la clase metodos, el loop for y el if else y como hacer un array. Y con esos conocimientos no tengo ni idea de como empezar o que hacer. He intentado hacer un for, un if, pero todo me da error, lo unico que he logrado hacer es el array y porque he mirado en google como declaralo bien, porque me daba error al no meterlo en un metodo. Os dejo lo que llevo. También me da un error en la clase main el IDE que estoy usando, que es eclipse.

1
2
3
4
5
6
7
8
9
10
11
12
13
public class exercise2 {
		static void method() {
	String [] weekDays = {"lunEs", "martes", "Lunes", "Miércoles", "friday", "lunes", "martes", "lunes", "miércoles", "friday"};
 
 
 
 
	public static void main(String[] args) {
 
	}
 
}
}
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 Kabuto
Val: 3.428
Oro
Ha mantenido su posición en Java (en relación al último mes)
Gráfica de Java

Devolver eliminando valores duplicados

Publicado por Kabuto (1381 intervenciones) el 20/09/2022 01:59:43
Hola.
Yo no diría que es un ejercicio básico.

Primero, si declaras el array FUERA del método main(), el método main() no podrá acceder a ese array si no lo declaras como static.
Esto se debe a que el método main() es static, así que solo puede acceder a variables y métodos que compartan el mismo ámbito, es decir, que sean static.

Para este ejercicio lo ideal es hacer un método que se encargue de eliminar los duplicados y retornar el array sin ellos. Así que este método también habrá que declararlo como static para poder invocarlo desde el main.

Este podría ser el programa, a falta de desarrollar el método que elimina duplicados.
Fíjate, insisto, que todos los elementos están declarados como static, para que estén en el mismo ámbito y puedan "verse" unos a otros.

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
public class Duplicados {
 
	private static String [] weekDays = {"lunEs", "martes", "Lunes", "Miércoles", "friday", "lunes", "martes", "lunes", "miércoles", "friday"};
 
	public static void main(String[] args) {
 
		System.out.println("Array original:");
 
		for (String dato: weekDays)
			System.out.print(dato + " ");
 
		String[] sinDuplicados = eliminarDuplicados(weekDays);
 
		System.out.println("\nArray sin duplicados:");
 
		for (String dato: sinDuplicados)
			System.out.print(dato + " ");
 
	}
 
	private static String[] eliminarDuplicados(String[] array) {
 
	}
 
}

Te estarás preguntando que es eso de static, y que diferencia hay entre ponerlo y no ponerlo.
Pues bien, olvídate de eso ahora. No es el momento y una explicación ahora te dejarás más dudas y no al revés. Más adelante, cuando empieces a ver la programación orientada a objetos más a fondo, será más fácil entender la diferencia entre ámbito estático y "no estático".

Centrémonos en el ejercicio que nos piden.
Como ves, el programa principal es sencillo. Mostramos el array original, luego pedimos al método que nos devuelva un nuevo array pero sin elementos duplicados y lo mostramos en pantalla para comprobar el resultado.

Ahora hay que desarrollar dicho método para ver como eliminamos elementos duplicados.

Lo primero que hay que tener en cuenta es que al comparar unos elementos con otros, debemos ignorar las mayúsculas y minúsculas.
Es decir, "lunEs" vamos a considerar que es lo mismo que "lunes"

Lo que podemos hacer es que cuando comparemos y encontremos un valor duplicado, ese valor duplicado podemos marcarlo como valor null, para "eliminarlo" del array.
Esto en realidad no hace que el array pierda un elemento, solo cambiar que ahora ese elemento tiene valor null.
Luego, no podemos retornar un array con valores null por todas partes, porque queda feo. Habrá que crear un nuevo array, con el tamaño necesario para poder pasarle los valores que NO se han marcado como null.

Este nuevo array será el que retornemos, sin valores null ni duplicados.

Este podría ser el código para esta tarea. Parece muy largo pero es porque está lleno de comentarios explicando. Si quitamos los comentarios en realidad, son menos de 20 líneas de código.
Si pudiéramos usar un ArrayList, sería mucho más sencillo. Pero supongo que debemos limitarnos a usar arrays "primitivos".
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
}
 
	private static String[] eliminarDuplicados(String[] array) {
 
		//Para evitar alterar el array original, hacemos una copia y trabajaremos sobre ella
		String[] copia = array.clone();
		/*
		 * Ahora buscaremos elementos duplicados.
		 * Con dos bucles anidados, compararemos cada elemento del array
		 * con los elementos restantes a partir de él.
		 * Al comparar, vamos a ignorar mayúsculas y minúsculas.
		 * Cuando encontramos un elemento duplicado, lo setearemos a valor null
		 * Así al terminar los bucles, todo lo que NO sea null, será un valor "no duplicado".
		 *
		 * Además contaremos los valores eliminados, para luego con una resta saber
		 * cuántos valores han "sobrevivido" sin ser cambiados a null.
		 */
		int eliminados = 0;
		for (int i = 0; i < copia.length; i++)
			for (int j = i+1; j < copia.length; j++)
				//Si valor actual NO es null Y al compararlo son IGUALES
				if (copia[i] != null && copia[i].equalsIgnoreCase(copia[j])) {
					copia[j] = null; //...tenemos un duplicado que hay que eliminar.
					eliminados++;
				}
		if (eliminados == 0) //Si por casualidad no se han encontrado duplicados
			return copia; //Pues listo, podemos retornar la copia tal cual y se acabó
		else { //pero en el caso de haber encontrado duplicados...
			/*
			 * Tenemos que crear un nuevo array quitando los valores marcados como null.
			 * Este nuevo array será más pequeño que la copia. Con el contador de eliminados
			 * podemos saber que tamaño ha de tener
			 */
			String[] nuevo = new String[copia.length - eliminados];
			/*
			 * Ahora volvemos a recorrer la copia y los valores que NO sean null
			 * los pasaremos al nuevo array.
			 * Como estos arrays tienen distintas medidas, habrá que usar dos
			 * índices distintos.
			 * El array copia lo recorreremos con el índice de un bucle FOR.
			 * Para el nuevo array, usaremos un índice separado que solo se incrementará
			 * cuando encontremos un valor no duplicado (que no es null)
			 */
			int indice = 0; //Índice para el nuevo array
			for (int i = 0; i < copia.length; i++)
				if (copia[i] != null) { //Valor NO duplicado
					nuevo[indice] = copia[i]; //Lo añadimos al nuevo array
					indice++; //Incrementamos índice
				}
			//Finalizado este bucle, ya tenemos el nuevo array relleno con los valores no duplicados
			return nuevo;
		}
	}

Vale, si probamos este código, en pantalla veremos que funciona:
1
2
3
4
Array original:
lunEs martes Lunes Miércoles friday lunes martes lunes miércoles friday
Array sin duplicados:
lunEs martes Miércoles friday

Pero falta un detalle. Los elementos "no duplicados" han de mostrarse con solo la primera letra en mayúscula.
Para esta tarea, podemos crear un segundo método, el cuál recibirá un String y construirá otro cambiando todas sus letras a minúscula, excepto la primera que pasará a mayúscula.
Este proceso se le llama "Capitalizar", así que ese puede ser el nombre de este método.

Y lo que haremos será llamarlo desde nuestro método anterior, justo en el momento en que pasamos valores "no duplicados" al nuevo array.
Así ya los pasaremos "capitalizados".
Marco en negrita ese momento:
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
}
 
	private static String[] eliminarDuplicados(String[] array) {
 
		//Para evitar alterar el array original, hacemos una copia y trabajaremos sobre ella
		String[] copia = array.clone();
		/*
		 * Ahora buscaremos elementos duplicados.
		 * Con dos bucles anidados, compararemos cada elemento del array
		 * con los elementos restantes a partir de él.
		 * Al comparar, vamos a ignorar mayúsculas y minúsculas.
		 * Cuando encontramos un elemento duplicado, lo setearemos a valor null
		 * Así al terminar los bucles, todo lo que NO sea null, será un valor "no duplicado".
		 *
		 * Además contaremos los valores eliminados, para luego con una resta saber
		 * cuántos valores han "sobrevivido" sin ser cambiados a null.
		 */
		int eliminados = 0;
		for (int i = 0; i < copia.length; i++)
			for (int j = i+1; j < copia.length; j++)
				//Si valor actual NO es null Y al compararlo son IGUALES
				if (copia[i] != null && copia[i].equalsIgnoreCase(copia[j])) {
					copia[j] = null; //...tenemos un duplicado que hay que eliminar.
					eliminados++;
				}
		if (eliminados == 0) //Si por casualidad no se han encontrado duplicados
			return copia; //Pues listo, podemos retornar la copia tal cual y se acabó
		else { //pero en el caso de haber encontrado duplicados...
			/*
			 * Tenemos que crear un nuevo array quitando los valores marcados como null.
			 * Este nuevo array será más pequeño que la copia. Con el contador de eliminados
			 * podemos saber que tamaño ha de tener
			 */
			String[] nuevo = new String[copia.length - eliminados];
			/*
			 * Ahora volvemos a recorrer la copia y los valores que NO sean null
			 * los pasaremos al nuevo array.
			 * Como estos arrays tienen distintas medidas, habrá que usar dos
			 * índices distintos.
			 * El array copia lo recorreremos con el índice de un bucle FOR.
			 * Para el nuevo array, usaremos un índice separado que solo se incrementará
			 * cuando encontremos un valor no duplicado (que no es null)
			 */
			int indice = 0; //Índice para el nuevo array
			for (int i = 0; i < copia.length; i++)
				if (copia[i] != null) { //Valor NO duplicado
					nuevo[indice] = capitalizarString(copia[i]); //Lo añadimos al nuevo array, capitalizando
					indice++; //Incrementamos índice
				}
			//Finalizado este bucle, ya tenemos el nuevo array relleno con los valores no duplicados
			return nuevo;
		}
	}
 
	private static String capitalizarString(String cadena) {
		/*
		 * Crearemos un nuevo String, con la primera letra mayúscula
		 * y el resto en minúscula.
		 * Podemos usar la clase StringBuilder para ir construyendo la cadena
		 * letra a letra.
		 */
 
		StringBuilder nueva = new StringBuilder();
		for (int i = 0; i < cadena.length(); i++) {
			String letra = cadena.substring(i, i+1);//Extraemos una letra
			if (i == 0) //Si es la primera letra...
				nueva.append(letra.toUpperCase()); //La queremos mayúscula
			else //El resto de letras...
				nueva.append(letra.toLowerCase()); //Las queremos minúculas.
		}
		//Nueva cadena construida, la retornamos
		return nueva.toString();
	}


Si ahora volvemos a probar el código, veremos que ahora sí tenemos los valores como pide el ejercicio:
1
2
3
4
Array original:
lunEs martes Lunes Miércoles friday lunes martes lunes miércoles friday
Array sin duplicados:
Lunes Martes Miércoles Friday

Creo que con la cantidad de comentarios que he puesto, ha quedado todo explicado.
Pero si algo no se entiende, solo tienes que preguntarlo.

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
1
Comentar
sin imagen de perfil

Devolver eliminando valores duplicados

Publicado por Pedro (7 intervenciones) el 20/09/2022 20:06:36
Esta todo perfectamente explicado, he seguido tus pasos y copiado el codigo a mano viendo que hace en cada momento para entenderlo mejor. Muchas gracias me has ayudado mucho.
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 Billy Joel
Val: 2.665
Oro
Ha mantenido su posición en Java (en relación al último mes)
Gráfica de Java

Devolver eliminando valores duplicados

Publicado por Billy Joel (876 intervenciones) el 20/09/2022 03:15:02
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
public class QuitarDuplicados {
 
    public static final String[] weekDays = {"lunEs", "martes", "Lunes", "Miércoles", "friday", "lunes", "martes", "lunes", "miércoles", "friday"};
 
    public static String[] mayusculas(String[] words) {
        String[] m = new String[words.length];
        for (int i = 0; i < m.length; i++) {
            m[i] = mayusculas(words[i]);
        }
        return m;
    }
 
    public static String mayusculas(String word) {
        return word.length() == 1 ? word.substring(0, 1).toUpperCase() : word.substring(0, 1).toUpperCase() + word.substring(1).toLowerCase();
    }
 
    public static String[] filtrarRepetidos(String[] words) {
        String r = "";
        for (String w : words) {
            if (!r.contains(w)) {
                r += r.isEmpty() ? w : "," + w;
            }
        }
        return r.split(",");
    }
 
    public static void main(String[] args) {
        String[] filtrados = filtrarRepetidos(mayusculas(weekDays));
        System.out.println("Filtrados: ");
        for (String w : filtrados) {
            System.out.println(w);
        }
    }
}

Saludos,
Billy Joel
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