Eliminar duplicados de una cadena en Java

Estoy tratando de iterar a través de una cadena para eliminar los caracteres duplicados.

Por ejemplo, la cadena aabbccdef debería convertirse en abcdef y la cadena abcdabcd debería convertirse en abcd

Esto es lo que tengo hasta ahora:

 public class test { public static void main(String[] args) { String input = new String("abbc"); String output = new String(); for (int i = 0; i < input.length(); i++) { for (int j = 0; j < output.length(); j++) { if (input.charAt(i) != output.charAt(j)) { output = output + input.charAt(i); } } } System.out.println(output); } } 

¿Cuál es la mejor manera de hacer esto?

Convierta la cadena a una matriz de char, y guárdela en un LinkedHashSet . Eso preservará su orden y eliminará duplicados. Algo como:

 String string = "aabbccdefatafaz"; char[] chars = string.toCharArray(); Set charSet = new LinkedHashSet(); for (char c : chars) { charSet.add(c); } StringBuilder sb = new StringBuilder(); for (Character character : charSet) { sb.append(character); } System.out.println(sb.toString()); 

Usaría la ayuda de LinkedHashSet . Elimina dups (ya que estamos utilizando un conjunto, mantiene el orden ya que estamos utilizando la lista vinculada impl). Esta es una especie de solución sucia. podría haber incluso una mejor manera.

 String s="aabbccdef"; Set set=new LinkedHashSet(); for(char c:s.toCharArray()) { set.add(Character.valueOf(c)); } 

Prueba esta simple solución:

 public String removeDuplicates(String input){ String result = ""; for (int i = 0; i < input.length(); i++) { if(!result.contains(String.valueOf(input.charAt(i)))) { result += String.valueOf(input.charAt(i)); } } return result; } 

Crea un StringWriter. Ejecute la cadena original usando charAt (i) en un ciclo for. Mantenga una variable de tipo char manteniendo el último valor de charAt. Si itera y el valor de charAt es igual a lo que está almacenado en esa variable, no lo agregue al StringWriter. Finalmente, use el método StringWriter.toString () y obtenga una cadena, y haga lo que necesite con ella.

Usar Stream lo hace fácil.

 import java.util.Arrays; import java.util.stream.Collectors; public class MyClass { public static String removeDuplicates(String myString) { return Arrays.asList(myString.split("")).stream().distinct().collect(Collectors.joining()); } } 

Aquí hay más documentación sobre Stream y todo lo que puede hacer con ella: https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html

La parte de ‘descripción’ es muy instructiva sobre los beneficios de Streams.

  String input = "AAAB"; String output = ""; for (int index = 0; index < input.length(); index++) { if (input.charAt(index % input.length()) != input .charAt((index + 1) % input.length())) { output += input.charAt(index); } } System.out.println(output); 

pero no puede usarlo si la entrada tiene los mismos elementos, o si está vacía.

Código para eliminar los caracteres duplicados en una cadena sin usar ningún búfer adicional. NOTA: Una o dos variables adicionales están bien. Una matriz extra no es:

 import java.util.*; public class Main{ public static char[] removeDupes(char[] arr){ if (arr == null || arr.length < 2) return arr; int len = arr.length; int tail = 1; for(int x = 1; x < len; x++){ int y; for(y = 0; y < tail; y++){ if (arr[x] == arr[y]) break; } if (y == tail){ arr[tail] = arr[x]; tail++; } } return Arrays.copyOfRange(arr, 0, tail); } public static char[] bigArr(int len){ char[] arr = new char[len]; Random r = new Random(); String alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#$%^&*()-=_+[]{}|;:',.<>/?`~"; for(int x = 0; x < len; x++){ arr[x] = alphabet.charAt(r.nextInt(alphabet.length())); } return arr; } public static void main(String args[]){ String result = new String(removeDupes(new char[]{'a', 'b', 'c', 'd', 'a'})); assert "abcd".equals(result) : "abcda should return abcd but it returns: " + result; result = new String(removeDupes(new char[]{'a', 'a', 'a', 'a'})); assert "a".equals(result) : "aaaa should return a but it returns: " + result; result = new String(removeDupes(new char[]{'a', 'b', 'c', 'a'})); assert "abc".equals(result) : "abca should return abc but it returns: " + result; result = new String(removeDupes(new char[]{'a', 'a', 'b', 'b'})); assert "ab".equals(result) : "aabb should return ab but it returns: " + result; result = new String(removeDupes(new char[]{'a'})); assert "a".equals(result) : "a should return a but it returns: " + result; result = new String(removeDupes(new char[]{'a', 'b', 'b', 'a'})); assert "ab".equals(result) : "abba should return ab but it returns: " + result; char[] arr = bigArr(5000000); long startTime = System.nanoTime(); System.out.println("2: " + new String(removeDupes(arr))); long endTime = System.nanoTime(); long duration = (endTime - startTime); System.out.println("Program took: " + duration + " nanoseconds"); System.out.println("Program took: " + duration/1000000000 + " seconds"); } } 

Cómo leer y hablar sobre el código anterior:

  1. El método llamado removeDupes toma una matriz de caracteres primitivos llamada arr.
  2. arr se devuelve como una matriz de caracteres primitivos "por valor". El archivo pasado es basura recolectada al final del método miembro de Main, removeDupes.
  3. La complejidad del tiempo de ejecución de este algoritmo es O (n) o más específicamente O (n + (pequeña constante)) siendo la constante los caracteres únicos en toda la matriz de caracteres primitivos.
  4. El copyOfRange no aumenta significativamente la complejidad del tiempo de ejecución ya que solo copia una pequeña cantidad constante de elementos. La matriz de caracteres llamada arr no tiene un paso completo.
  5. Si pasa null a removeDupes, el método devuelve null.
  6. Si pasa una matriz vacía de caracteres primitivos o una matriz que contiene un valor, se devuelve esa matriz no modificada.
  7. El método removeDupes funciona lo más rápido posible físicamente, utilizando completamente el caché L1 y L2, por lo que las redirecciones de Branch se mantienen al mínimo .
  8. Una computadora descargada estándar de 2015 debería poder completar este método con una matriz de caracteres primitiva que contenga 500 millones de caracteres entre 15 y 25 segundos.

Explica cómo funciona este código:

La primera parte de la matriz pasada se usa como el repository de los caracteres únicos que finalmente se devuelven. Al comienzo de la función, la respuesta es: "los caracteres entre 0 y 1" están entre 0 y la cola.

Definimos la variable y fuera del ciclo porque queremos encontrar la primera ubicación donde el índice de la matriz que estamos viendo ha sido duplicado en nuestro repository. Cuando se encuentra un duplicado, se rompe y se cierra, y == tail devuelve false y no se contribuye al repository.

cuando el índice x que estamos observando no está representado en nuestro repository, lo extraemos y lo agregamos al final de nuestro repository en la cola del índice e incrementamos la cola.

Al final, devolvemos la matriz entre los puntos 0 y la cola, que debe ser menor o igual a la longitud de la matriz original.

Ejercicio de puntos parlantes para entrevistas de codificadores:

¿Se comportará el progtwig de manera diferente si cambia el y ++ a ++ y? Por qué o por qué no.

¿La copia de la matriz al final representa otra pasada 'N' a través de toda la matriz que hace que la complejidad del tiempo de ejecución sea O (n * n) en lugar de O (n)? Por qué o por qué no.

¿Puedes reemplazar el doble igual al comparar personajes primitivos con un .equals? ¿Por qué o por qué no?

¿Se puede cambiar este método para hacer los reemplazos "por referencia" en lugar de como está ahora, "por valor"? ¿Por qué o por qué no?

¿Se puede boost la eficacia de este algoritmo clasificando el repository de valores únicos al principio de 'arr'? ¿En qué circunstancias sería más eficiente?

 public class RemoveRepeated4rmString { public static void main(String[] args) { String s = "harikrishna"; String s2 = ""; for (int i = 0; i < s.length(); i++) { Boolean found = false; for (int j = 0; j < s2.length(); j++) { if (s.charAt(i) == s2.charAt(j)) { found = true; break; //don't need to iterate further } } if (found == false) { s2 = s2.concat(String.valueOf(s.charAt(i))); } } System.out.println(s2); } } 

Aquí hay una mejora en la respuesta de Dave .

Utiliza HashSet lugar de LinkedHashSet , un poco más costoso, y reutiliza el búfer de chars para el resultado, eliminando la necesidad de un StringBuilder .

 String string = "aabbccdefatafaz"; char[] chars = string.toCharArray(); Set present = new HashSet<>(); int len = 0; for (char c : chars) if (present.add(c)) chars[len++] = c; System.out.println(new String(chars, 0, len)); // abcdeftz 

Para mí, parece que todos están esforzándose demasiado para lograr esta tarea. Todo lo que nos preocupa es que copia 1 copia de cada letra si se repite. Entonces, como nos preocupa que esos personajes se repitan uno tras otro, los bucles nesteds se vuelven arbitrarios, ya que simplemente puede comparar la posición n con la posición n + 1. Entonces, como esto solo copia las cosas cuando son diferentes, resuelva el problema. último personaje, puede agregar espacios en blanco al final de la cadena original, o simplemente hacer que copie el último carácter de la cadena a su resultado.

String removeDuplicate (String s) {

  String result = ""; for (int i = 0; i < s.length(); i++){ if (i + 1 < s.length() && s.charAt(i) != s.charAt(i+1)){ result = result + s.charAt(i); } if (i + 1 == s.length()){ result = result + s.charAt(i); } } return result; } 

No puedes. Puede crear una nueva Cadena que tenga duplicados eliminados. ¿Por qué no estás usando StringBuilder (o StringBuffer, presumiblemente)?

Puede ejecutar la cadena y almacenar los caracteres únicos en una matriz char [], haciendo un seguimiento de la cantidad de caracteres únicos que ha visto. Luego puede crear una nueva cadena usando el constructor String(char[], int, int) .

Además, el problema es un poco ambiguo: ¿”duplicados” significa repeticiones adyacentes? (En otras palabras, ¿qué debería pasar con abcab ?)

De acuerdo Chicos, he encontrado una mejor manera de hacer esto

 public static void alpha(char[] finalname) { if (finalname == null) { return; } if (finalname.length <2) { return; } char empty = '\000'; for (int i=0; i 

Oldschool way (como escribimos tales tareas en Apple) [Básico, adaptado a Java]:

 int i,j; StringBuffer str=new StringBuffer(); Scanner in = new Scanner(System.in); System.out.print("Enter string: "); str.append(in.nextLine()); for (i=0;i 

Aquí hay otra lógica que me gustaría compartir. Empiezas a comparar desde la mitad de la longitud de la cuerda e ir hacia atrás.

Prueba con: input = “azxxzy”; salida = “ay”;

 String removeMidway(String input){ cnt = cnt+1; StringBuilder str = new StringBuilder(input); int midlen = str.length()/2; for(int i=midlen-1;i>0;i--){ for(int j=midlen;j
		      	

Este es otro enfoque

 void remove_duplicate (char* str, int len) { unsigned int index = 0; int c = 0; int i = 0; while (c < len) { /* this is just example more check can be added for capital letter, space and special chars */ int pos = str[c] - 'a'; if ((index & (1< 

Otra posible solución, en caso de que una cadena sea una cadena ASCII, es mantener una matriz de 256 elementos booleanos para denotar la aparición de caracteres ASCII en una cadena. Si un personaje apareció por primera vez, lo guardamos y añadimos al resultado. De lo contrario, sáltelo.

 public String removeDuplicates(String input) { boolean[] chars = new boolean[256]; StringBuilder resultStringBuilder = new StringBuilder(); for (Character c : input.toCharArray()) { if (!chars[c]) { resultStringBuilder.append(c); chars[c] = true; } } return resultStringBuilder.toString(); } 

Este enfoque también funcionará con la cadena Unicode. Solo necesitas boost el tamaño de los chars .

Solución usando JDK7:

 public static String removeDuplicateChars(final String str){ if (str == null || str.isEmpty()){ return str; } final char[] chArray = str.toCharArray(); final Set set = new LinkedHashSet<>(); for (char c : chArray) { set.add(c); } final StringBuilder sb = new StringBuilder(); for (Character character : set) { sb.append(character); } return sb.toString(); } 
  public static void main(String a[]){ String name="Madan"; System.out.println(name); StringBuilder sb=new StringBuilder(name); for(int i=0;i 
  String str = "eamparuthik@gmail.com"; char[] c = str.toCharArray(); String op = ""; for(int i=0; i<=c.length-1; i++){ if(!op.contains(c[i] + "")) op = op + c[i]; } System.out.println(op); 
 public static String removeDuplicateChar(String str){ char charArray[] = str.toCharArray(); StringBuilder stringBuilder= new StringBuilder(); for(int i=0;i 
 import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; public class RemoveDuplicacy { public static void main(String args[])throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); System.out.print("Enter any word : "); String s = br.readLine(); int l = s.length(); char ch; String ans=" "; for(int i=0; i 
 import java.util.Scanner; public class dublicate { public static void main(String... a) { System.out.print("Enter the String"); Scanner Sc = new Scanner(System.in); String st=Sc.nextLine(); StringBuilder sb=new StringBuilder(); boolean [] bc=new boolean[256]; for(int i=0;i 
 public static void main(String[] args) { int i,j; StringBuffer str=new StringBuffer(); Scanner in = new Scanner(System.in); System.out.print("Enter string: "); str.append(in.nextLine()); for (i=0;i 

Esta es una mejora en la solución sugerida por @Dave. Aquí, estoy implementando en solo lazo único.

Reutilicemos el método de devolución de set.add (elemento T) y añádalo simultáneamente en StringBuffer si add es exitoso.

Esto es solo O (n). No es necesario hacer un bucle de nuevo.

 String string = "aabbccdefatafaz"; char[] chars = string.toCharArray(); StringBuilder sb = new StringBuilder(); Set charSet = new LinkedHashSet(); for (char c : chars) { if(charSet.add(c) ){ sb.append(c); } } System.out.println(sb.toString()); // abcdeftz 

La solución simple es iterar a través de la cadena dada y poner cada carácter único en otra cadena (en este caso, un resultado de variable) si esta cadena no contiene ese carácter en particular. Finalmente devuelva la cadena resultante como salida.

A continuación se muestra un fragmento de código probado y probado para eliminar caracteres duplicados de la cadena dada que tiene una complejidad de tiempo O (n).

 private static String removeDuplicate(String s) { String result=""; for (int i=0 ;i 

Si la entrada es señora, entonces la salida será loca .
Si la entrada es un anagtwig , la salida será angrm

Espero que esto ayude.
Gracias

Para la simplicidad del código, he tomado la entrada hardcore, uno puede tomar entrada usando la clase Scanner también

  public class KillDuplicateCharInString { public static void main(String args[]) { String str= "aaaabccdde "; char arr[]= str.toCharArray(); int n = arr.length; String finalStr=""; for(int i=0;i 
  public static void main (String[] args) { Scanner sc = new Scanner(System.in); String s = sc.next(); String str = ""; char c; for(int i = 0; i < s.length(); i++) { c = s.charAt(i); str = str + c; s = s.replace(c, ' '); if(i == s.length() - 1) { System.out.println(str.replaceAll("\\s", "")); } } } 
 package com.st.removeduplicate; public class RemoveDuplicate { public static void main(String[] args) { String str1="shushil",str2=""; for(int i=0; i<=str1.length()-1;i++) { int count=0; for(int j=0;j<=i;j++) { if(str1.charAt(i)==str1.charAt(j)) count++; if(count >1) break; } if(count==1) str2=str2+str1.charAt(i); } System.out.println(str2); } 

}

paquete com.core.interview.client;

importar java.util.LinkedHashSet;

import java.util.Scanner;

import java.util.Set;

clase pública RemoveDuplicateFromString {

 public static String DupRemoveFromString(String str){ char[] c1 =str.toCharArray(); Set charSet = new LinkedHashSet(); for(char c:c1){ charSet.add(c); } StringBuffer sb = new StringBuffer(); for (Character c2 : charSet) { sb.append(c2); } return sb.toString(); } public static void main(String[] args) { System.out.println("Enter Your String: "); Scanner sc = new Scanner(System.in); String str = sc.nextLine(); System.out.println(DupRemoveFromString(str)); } 

}

Espero que esto ayude

 public void RemoveDuplicates() { String s = "Hello World!"; int l = s.length(); char ch; String result = ""; for (int i = 0; i < l; i++) { ch = s.charAt(i); if (ch != ' ') { result = result + ch; } // Replacing space in all occurrence of the current character s = s.replace(ch, ' '); } System.out.println("After removing duplicate characters : " + result); }