Suppression de caractères répétés d'une chaîne

1. Vue d'ensemble

Dans ce didacticiel, nous aborderons plusieurs techniques en Java sur la façon de supprimer des caractères répétés d'une chaîne.

Pour chaque technique, nous parlerons également brièvement de sa complexité temporelle et spatiale.

2. Utilisation distincte

Commençons par supprimer les doublons de notre chaîne en utilisant la méthode distincte introduite dans Java 8.

Ci-dessous, nous obtenons une instance d'un tream Int S à partir d'un objet string donné. Ensuite, nous utilisons la méthode distincte pour supprimer les doublons. Enfin, nous appelons la méthode forEach pour boucler sur les caractères distincts et les ajouter à notre StringBuilder :

StringBuilder sb = new StringBuilder(); str.chars().distinct().forEach(c -> sb.append((char) c));

Complexité temporelle: O (n) - le temps d'exécution de la boucle est directement proportionnel à la taille de la chaîne d'entrée

Espace auxiliaire: O (n) - puisque distinct utilise un LinkedHashSet en interne et nous stockons également la chaîne résultante dans un objet StringBuilder

Maintient l'ordre: Oui - puisque le LinkedHashSet maintient l'ordre de ses éléments

Et, bien que ce soit bien que Java 8 fasse si bien cette tâche pour nous, comparons-le aux efforts pour lancer le nôtre.

3. Utilisation d' indexOf

L'approche naïve pour supprimer les doublons d'une chaîne implique simplement de boucler sur l'entrée et d'utiliser la méthode indexOf pour vérifier si le caractère actuel existe déjà dans la chaîne résultante :

StringBuilder sb = new StringBuilder(); int idx; for (int i = 0; i < str.length(); i++) { char c = str.charAt(i); idx = str.indexOf(c, i + 1); if (idx == -1) { sb.append(c); } } 

Complexité temporelle: O (n * n) - pour chaque caractère, la méthode indexOf parcourt la chaîne restante

Espace auxiliaire: O (n) - l'espace linéaire est requis car nous utilisons le StringBuilder pour stocker le résultat

Maintient l'ordre: Oui

Cette méthode a la même complexité spatiale que la première approche mais fonctionne beaucoup plus lentement.

4. Utilisation d'un tableau de caractères

Nous pouvons également supprimer les doublons de notre chaîne en le convertissant en un omble chevalier tableau et puis boucler sur chaque personnage et en le comparant à tous les caractères suivants .

Comme nous pouvons le voir ci-dessous, nous créons deux boucles for et nous vérifions si chaque élément est répété dans la chaîne. Si un doublon est trouvé, nous ne l'ajoutons pas au StringBuilder :

char[] chars = str.toCharArray(); StringBuilder sb = new StringBuilder(); boolean repeatedChar; for (int i = 0; i < chars.length; i++) { repeatedChar = false; for (int j = i + 1; j < chars.length; j++) { if (chars[i] == chars[j]) { repeatedChar = true; break; } } if (!repeatedChar) { sb.append(chars[i]); } } 

Complexité temporelle: O (n * n) - nous avons une boucle interne et une boucle externe traversant la chaîne d'entrée

Espace auxiliaire: O (n) - un espace linéaire est requis car la variable chars stocke une nouvelle copie de l'entrée de chaîne et nous utilisons également le StringBuilder pour enregistrer le résultat

Maintient l'ordre: Oui

Encore une fois, notre deuxième tentative fonctionne mal par rapport à l'offre Core Java, mais voyons où nous en sommes avec notre prochaine tentative.

5. Utilisation du tri

Alternativement, les caractères répétés peuvent être éliminés en triant notre chaîne d'entrée pour regrouper les doublons. Pour ce faire, nous devons convertir la chaîne en char a rray et la trier à l'aide des tableaux . méthode de tri . Enfin, nous allons parcourir la Sorted omble tableau.

A chaque itération, nous allons comparer chaque élément du tableau avec l'élément précédent. Si les éléments sont différents, nous ajouterons le caractère actuel au StringBuilder:

StringBuilder sb = new StringBuilder(); if(!str.isEmpty()) { char[] chars = str.toCharArray(); Arrays.sort(chars); sb.append(chars[0]); for (int i = 1; i < chars.length; i++) { if (chars[i] != chars[i - 1]) { sb.append(chars[i]); } } }

Complexité temporelle: O (n log n) - le tri utilise un tri rapide à double pivot qui offre des performances O (n log n) sur de nombreux ensembles de données

Espace auxiliaire: O (n) - puisque la méthode toCharArray fait une copie de la chaîne d' entrée

Maintient l'ordre: Non

Essayons à nouveau avec notre dernière tentative.

6. Utilisation d'un ensemble

Un autre moyen de supprimer des caractères répétés d'une chaîne consiste à utiliser un ensemble . Si nous ne nous soucions pas de l'ordre des caractères dans notre chaîne de sortie, nous pouvons utiliser un HashSet . Sinon, nous pouvons utiliser un LinkedHashSet pour maintenir l'ordre d'insertion.

Dans les deux cas, nous allons boucler sur la chaîne d'entrée et ajouter chaque caractère à l' ensemble . Une fois les caractères insérés dans l'ensemble, nous allons itérer dessus pour les ajouter au StringBuilder et renvoyer la chaîne résultante:

StringBuilder sb = new StringBuilder(); Set linkedHashSet = new LinkedHashSet(); for (int i = 0; i < str.length(); i++) { linkedHashSet.add(str.charAt(i)); } for (Character c : linkedHashSet) { sb.append(c); } 

Complexité temporelle: O (n) - le temps d'exécution de la boucle est directement proportionnel à la taille de la chaîne d'entrée

Espace auxiliaire: O (n) - l'espace requis pour l' ensemble dépend de la taille de la chaîne d'entrée; aussi, nous utilisons le StringBuilder pour stocker le résultat

Maintient l'ordre: LinkedHashSet - Oui, HashSet - Non

Et maintenant, nous avons adapté l'approche Core Java! Il n'est pas très choquant de découvrir que c'est très similaire à ce que fait déjà distinct .

7. Conclusion

Dans cet article, nous avons couvert quelques façons de supprimer des caractères répétés d'une chaîne en Java. Nous avons également examiné la complexité temporelle et spatiale de chacune de ces méthodes.

Comme toujours, des extraits de code peuvent être trouvés sur GitHub.