manejo funciones ejemplos caracteres caracter cadenas cadena buscar arreglo agregar java arrays string duplicate-removal

java - funciones - Eliminar cadenas con los mismos caracteres en una matriz de cadenas



funciones string java (4)

Estoy enfrentando un problema en este momento. En uno de mis programas, necesito eliminar cadenas con los mismos caracteres de una matriz. Por ej. suponer,

Tengo 3 matrices como,

String[] name1 = {"amy", "jose", "jeremy", "alice", "patrick"}; String[] name2 = {"alan", "may", "jeremy", "helen", "alexi"}; String[] name3 = {"adel", "aron", "amy", "james", "yam"};

Como puede ver, hay un String amy en la matriz name1 . Además, tengo cadenas como may , amy y yam en las siguientes dos matrices. Lo que necesito es eso, necesito una matriz final que no contenga estas cadenas repetidas. Solo necesito una ocurrencia: necesito eliminar todas las permutaciones de un nombre en la matriz final. Esa es la matriz final debe ser:

String[] finalArray={"amy", "jose", "alice", "patrick","alan", "jeremy", "helen", "alexi","adel", "aron", "james"}

(La matriz anterior eliminó tanto yam, puede y solo incluye amy).

Lo que he intentado hasta ahora, usando HashSet , es el siguiente

String[] name1 = {"Amy", "Jose", "Jeremy", "Alice", "Patrick"}; String[] name2 = {"Alan", "mAy", "Jeremy", "Helen", "Alexi"}; String[] name3 = {"Adel", "Aaron", "Amy", "James", "Alice"}; Set<String> letter = new HashSet<String>(); for (int i = 0; i < name1.length; i++) { letter.add(name1[i]); } for (int j = 0; j < name2.length; j++) { letter.add(name2[j]); } for (int k = 0; k < name3.length; k++) { letter.add(name3[k]); } System.out.println(letter.size() + " letters must be sent to: " + letter);

Pero, el problema con este código es que, simplemente elimina múltiples ocurrencias de la misma cadena. ¿Hay otra alternativa? Cualquier ayuda es muy apreciada.


Una alternativa, Java 8, solución.

1) Crear un Map<String, List<String> con la forma normalizada y luego ver todas las formas diferentes

public static Map<String, List<String>> groupNormalised(final String[]... input) { return Arrays.stream(input) .flatMap(Arrays::stream) .collect(Collectors.groupingBy(s -> { char[] c = s.toCharArray(); Arrays.sort(c); return new String(c); })); }

Ejemplo:

Map<String, List<String>> grouped = groupNormalised(name1, name2, name3); grouped.forEach((k, v) -> System.out.printf("%s appears as %s%n", k, v));

Salida:

eejmry appears as [jeremy, jeremy] aceil appears as [alice] eehln appears as [helen] ejos appears as [jose] adel appears as [adel] aeilx appears as [alexi] acikprt appears as [patrick] aejms appears as [james] amy appears as [amy, may, amy, yam] anor appears as [aron] aaln appears as [alan]

2) Procese el Map para extraer los datos que desee

Ahora tiene una opción, puede crear un Set de formularios normalizados:

final Set<String> normalisedForms = grouped.keySet();

O puede crear un Set de los primeros encuentros:

final Set<String> first = grouped.values().stream() .map(c -> c.iterator().next()) .collect(toSet());

O como una matriz:

final String[] first = grouped.values().stream() .map(c -> c.iterator().next()) .toArray(String[]::new);


En línea con kdm:

import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Set; public class RemoveDuplicateString { private static boolean add(Set<String> keySet, String s){ char[] sortCharacters = s.toCharArray(); Arrays.sort(sortCharacters); return keySet.add(new String(sortCharacters)); } private static void check(Set<String> keySet, String []names, List<String> result){ for (String name : names) { if (add(keySet, name)){ result.add(name); } } } public static void main(String[] args) { String[] name1 = {"amy", "jose", "jeremy", "alice", "patrick"}; String[] name2 = {"alan", "may", "jeremy", "helen", "alexi"}; String[] name3 = {"adel", "aron", "amy", "james", "yam"}; Set<String> keySet = new HashSet<String>(); List<String> result = new ArrayList<String>(); check(keySet, name1, result); check(keySet, name2, result); check(keySet, name3, result); System.out.println(result); } }


Puede ordenar la matriz de caracteres de String ( str.toCharArray () ) y crear una nueva cadena de la matriz ordenada para obtener una representación "canónica" de una cadena.

Luego puede agregar estas Cadenas a un Set y verificar para cada Cadena si la representación canónica ya está en el Conjunto.

Set<String> letter = new HashSet<String>(); for (int i = 0; i < name1.length; i++) { char[] chars = name1[i].toCharArray(); Arrays.sort(chars); letter.add(new String(chars)); } for (int j = 0; j < name2.length; j++) { char[] chars = name2[j].toCharArray(); Arrays.sort(chars); letter.add(new String(chars)); } for (int k = 0; k < name3.length; k++) { char[] chars = name3[k].toCharArray(); Arrays.sort(chars); letter.add(new String(chars)); }

EDITAR: Cambié el Set<char[]> a Set<String> , ya que las matrices no anulan hashCode e equals , por lo que HashSet<char[]> no funcionaría.


TreeSet nos permite dar un comparador. Vea si esto ayuda. Para mantener el conteo usa un TreeMap .

package empty; import java.util.Arrays; import java.util.Comparator; import java.util.Set; import java.util.TreeMap; import java.util.TreeSet; public class RemoveDuplicateStrings { public static void main(String[] args) { String[] name1 = { "amy", "jose", "jeremy", "alice", "patrick" }; String[] name2 = { "alan", "may", "jeremy", "helen", "alexi" }; String[] name3 = { "adel", "aron", "amy", "james", "yam" }; Comparator<String> comparator = new Comparator<String>() { @Override public int compare(String o1, String o2) { System.out.println("Compare(" + o1 + "," + o2 + ")"); char[] a1 = o1.toCharArray(); Arrays.sort(a1); char[] a2 = o2.toCharArray(); Arrays.sort(a2); return new String(a1).compareTo(new String(a2)); } }; Set<String> set = new TreeSet<String>(comparator); for (String name : name1) { set.add(name); } for (String name : name2) { set.add(name); } for (String name : name3) { set.add(name); } String[] result = set.toArray(new String[set.size()]); System.out.println(Arrays.asList(result)); // Using TreeMap to keep the count. TreeMap<String, Integer> map = new TreeMap<String, Integer>(comparator); addAll(name1, map); addAll(name2, map); addAll(name3, map); System.out.println(map); } private static void addAll(String[] names, TreeMap<String, Integer> map) { for (String name : names) { if (map.containsKey(name)) { int n = map.get(name); map.put(name, n + 1); } else map.put(name, 1); } } }