Le code suivant tente de supprimer les caractères en double d'une chaîne. Je ne suis pas sûr si le code est correct. Quelqu'un peut-il m'aider à travailler avec le code (c'est-à-dire ce qui se passe réellement lorsqu'il y a une correspondance dans les caractères)?
public static void removeDuplicates(char[] str) {
if (str == null) return;
int len = str.length;
if (len < 2) return;
int tail = 1;
for (int i = 1; i < len; ++i) {
int j;
for (j = 0; j < tail; ++j) {
if (str[i] == str[j]) break;
}
if (j == tail) {
str[tail] = str[i];
++tail;
}
}
str[tail] = 0;
}
La fonction me semble bien. J'ai écrit des commentaires en ligne. J'espère que ça aide:
// function takes a char array as input.
// modifies it to remove duplicates and adds a 0 to mark the end
// of the unique chars in the array.
public static void removeDuplicates(char[] str) {
if (str == null) return; // if the array does not exist..nothing to do return.
int len = str.length; // get the array length.
if (len < 2) return; // if its less than 2..can't have duplicates..return.
int tail = 1; // number of unique char in the array.
// start at 2nd char and go till the end of the array.
for (int i = 1; i < len; ++i) {
int j;
// for every char in outer loop check if that char is already seen.
// char in [0,tail) are all unique.
for (j = 0; j < tail; ++j) {
if (str[i] == str[j]) break; // break if we find duplicate.
}
// if j reachs tail..we did not break, which implies this char at pos i
// is not a duplicate. So we need to add it our "unique char list"
// we add it to the end, that is at pos tail.
if (j == tail) {
str[tail] = str[i]; // add
++tail; // increment tail...[0,tail) is still "unique char list"
}
}
str[tail] = 0; // add a 0 at the end to mark the end of the unique char.
}
Je suis désolé de dire que votre code est très similaire à C.
Une Java String
n'est pas un char[]
. Vous dites que vous voulez supprimer les doublons d'une String
, mais vous prenez plutôt un char[]
.
Ce char[]
\0
- est-il terminé? Ne ressemble pas à ça parce que vous prenez la totalité du .length
du tableau. Mais ensuite, votre algorithme essaie de \0
- terminer une partie du tableau. Que se passe-t-il si les tableaux ne contiennent pas de doublons?
Eh bien, comme il est écrit, votre code jette en fait une ArrayIndexOutOfBoundsException
sur la dernière ligne! Il n'y a pas de place pour le \0
car tous les slots sont utilisés!
Vous pouvez ajouter un chèque pour ne pas ajouter \0
dans ce cas exceptionnel, mais comment comptez-vous quand même utiliser ce code? Envisagez-vous d'avoir une fonction semblable à strlen
- pour trouver le premier \0
dans le tableau? Et que se passe-t-il s'il n'y en a pas? (en raison de tous les cas exceptionnels ci-dessus?).
Que se passe-t-il si la variable String
/char[]
contient un \0
? (Ce qui est parfaitement légal en Java, en passant, voir JLS 10.9 Un tableau de caractères n'est pas une chaîne )
Le résultat sera désastreux, et tout cela parce que vous voulez tout faire comme un C et en place sans aucun tampon supplémentaire. Êtes-vous sûr d'avoir vraiment besoin de faire ça? Pourquoi ne pas utiliser String
, indexOf
, lastIndexOf
, replace
et toutes les API de niveau supérieur de String
? Est-ce que c'est manifestement trop lent ou vous en doutez seulement?
"L'optimisation prématurée est la racine de tous les maux". Je suis désolé, mais si vous ne comprenez même pas ce que fait le code original, déterminer comment il s'intégrera dans le système plus vaste (et plus compliqué) sera un cauchemar.
Ma suggestion minimale est de faire ce qui suit:
String
, c'est-à-dire public static String removeDuplicates(String in)
char[] str = in.toCharArray();
return new String(str, 0, tail);
Cela utilise des tampons supplémentaires, mais au moins l'interface avec le reste du système est beaucoup plus propre.
Sinon, vous pouvez utiliser StringBuilder
en tant que tel:
static String removeDuplicates(String s) {
StringBuilder noDupes = new StringBuilder();
for (int i = 0; i < s.length(); i++) {
String si = s.substring(i, i + 1);
if (noDupes.indexOf(si) == -1) {
noDupes.append(si);
}
}
return noDupes.toString();
}
Notez que ceci est essentiellement le même algorithme que ce que vous aviez, mais beaucoup plus propre et sans autant de petites cases, etc.
Étant donné la question suivante:
Écrivez un code pour supprimer les caractères en double dans une chaîne sans en utilisant un tampon supplémentaire . NOTE: Une ou deux variables supplémentaires sont bien. Une copie supplémentaire du tableau n'est pas.
Puisqu'une ou deux variables supplémentaires conviennent, mais qu'aucun tampon n'est autorisé, vous pouvez simuler le comportement d'une table de hachage en utilisant un entier pour stocker des bits. Cette solution simple fonctionne à O (n), ce qui est plus rapide que le vôtre. En outre, ce n'est pas compliqué sur le plan conceptuel et en place
public static void removeDuplicates(char[] str) {
int map = 0;
for (int i = 0; i < str.length; i++) {
if ((map & (1 << (str[i] - 'a'))) > 0) // duplicate detected
str[i] = 0;
else // add unique char as a bit '1' to the map
map |= 1 << (str[i] - 'a');
}
}
L'inconvénient est que les doublons (qui sont remplacés par des 0) ne seront pas placés à la fin du tableau str []. Cependant, cela peut facilement être corrigé en parcourant le tableau une dernière fois. En outre, un entier n'a la capacité que pour les lettres ordinaires.
private static String removeDuplicateCharactersFromWord(String Word) {
String result = new String("");
for (int i = 0; i < Word.length(); i++) {
if (!result.contains("" + Word.charAt(i))) {
result += "" + Word.charAt(i);
}
}
return result;
}
Ceci est ma solution au problème de la complexité en O (n ^ 2). L'idée est généralement la même que celle du livre, mais je crois que ma solution est plus lisible et plus facile à comprendre de l'algorithme lui-même:
private static void removeDuplicates(char[] str) {
if (str == null || str.length < 2) {
return;
}
int tail = 0;
for (int i = 0; i < str.length; i++) {
boolean found = false;
// check if character is already present in
// the part of the array before the current char
for (int j = 0; j < i; j++) {
if (str[j] == str[i]) {
found = true;
break;
}
}
// if char is already present
// skip this one and do not copy it
if (found) {
continue;
}
// copy the current char to the index
// after the last known unique char in the array
str[tail] = str[i];
tail++;
}
str[tail] = '\0';
}
char[] chars = s.toCharArray();
HashSet<Character> charz = new HashSet<Character>();
for(Character c : s.toCharArray() )
{
if(!charz.contains(c))
{
charz.add(c);
//System.out.print(c);
}
}
for(Character c : charz)
{
System.out.print(c);
}
public String removeDuplicateChar(String nonUniqueString) {
String uniqueString = "";
for (char currentChar : nonUniqueString.toCharArray()) {
if (!uniqueString.contains("" + currentChar)) {
uniqueString += currentChar;
}
}
return uniqueString;
}
Je comprends que c’est une question de Java, mais depuis que j’ai une solution de Nice qui pourrait inspirer quelqu'un à convertir cela en Java, à tout prix. J'aime aussi les réponses lorsque des soumissions en plusieurs langues sont disponibles pour des problèmes courants.
Voici donc une solution Python qui est O(n) et prend également en charge toute la gamme ASCII. Bien sûr, cela ne traite pas 'a' et 'A' comme identiques:
J'utilise 8 x 32 bits comme hashmap:
De plus, input est un tableau de chaînes utilisant dedup (list ('une chaîne'))
def dedup(str):
map = [0,0,0,0,0,0,0,0]
for i in range(len(str)):
ascii = ord(str[i])
slot = ascii / 32
bit = ascii % 32
bitOn = map[slot] & (1 << bit)
if bitOn:
str[i] = ''
else:
map[slot] |= 1 << bit
return ''.join(str)
un moyen plus pythonien de le faire consiste également à utiliser un ensemble:
def dedup(s):
return ''.join(list(set(s)))
public static void main (String [] args)
{
String s = "aabbbeeddsfre";//sample string
String temp2="";//string with no duplicates
HashMap<Integer,Character> tc = new HashMap<Integer,Character>();//create a hashmap to store the char's
char [] charArray = s.toCharArray();
for (Character c : charArray)//for each char
{
if (!tc.containsValue(c))//if the char is not already in the hashmap
{
temp2=temp2+c.toString();//add the char to the output string
tc.put(c.hashCode(),c);//and add the char to the hashmap
}
}
System.out.println(temp2);//final string
}
au lieu de HashMap, je pense que nous pouvons aussi utiliser Set.
Méthode de sous-chaîne. La concaténation est effectuée avec .concat()
pour éviter l'allocation de mémoire supplémentaire pour les mains gauche et droite du +
.
private static String withoutDuplicatesSubstringing(String s){
for(int i = 0; i < s.length(); i++){
String sub = s.substring(i+1);
int index = -1;
while((index = sub.toLowerCase().indexOf(Character.toLowerCase(s.charAt(i)))) > -1 && !sub.isEmpty()){
sub = sub.substring(0, index).concat(sub.substring(index+1, sub.length()));
}
s = s.substring(0, i+1).concat(sub);
}
return s;
}
Cas de test:
String testCase1 = "nanananaa! baaaaatmaan! batman!";
Sortie: na! btm
Une solution O(n):
import Java.util.*;
import Java.io.*;
public class String_Duplicate_Removal
{
public static String duplicate_removal(String s)
{
if(s.length()<2)
return s;
else if(s.length()==2)
{
if(s.charAt(0)==s.charAt(1))
s = Character.toString(s.charAt(0));
return s;
}
boolean [] arr = new boolean[26];
for(int i=0;i<s.length();i++)
{
if(arr[s.charAt(i)-'a']==false)
arr[s.charAt(i)-'a']=true;
else
{
s= ((new StringBuilder(s)).deleteCharAt(i)).toString();
i--;
}
}
return s;
}
public static void main(String [] args)
{
String s = "abbashbhqa";
System.out.println(duplicate_removal(s));
}
}
Je ne comprenais pas la logique de la solution, j'ai donc écrit ma solution simple:
public static void removeDuplicates(char[] str) {
if (str == null) return; //If the string is null return
int length = str.length; //Getting the length of the string
if (length < 2) return; //Return if the length is 1 or smaller
for(int i=0; i<length; i++){ //Loop through letters on the array
int j;
for(j=i+1;j<length;j++){ //Loop through letters after the checked letters (i)
if (str[j]==str[i]){ //If you find duplicates set it to 0
str[j]=0;
}
}
}
}
C'est ma solution
public static String removeDup(String inputString){
if (inputString.length()<2) return inputString;
if (inputString==null) return null;
char[] inputBuffer=inputString.toCharArray();
for (int i=0;i<inputBuffer.length;i++){
for (int j=i+1;j<inputBuffer.length;j++){
if (inputBuffer[i]==inputBuffer[j]){
inputBuffer[j]=0;
}
}
}
String result=new String(inputBuffer);
return result;
}
(Java) Éviter l'utilisation de structures de données Map, List:
private String getUniqueStr(String someStr) {
StringBuilder uniqueStr = new StringBuilder();
if(someStr != null) {
for(int i=0; i <someStr.length(); i++) {
if(uniqueStr.indexOf(String.valueOf(someStr.charAt(i))) == -1) {
uniqueStr.append(someStr.charAt(i));
}
}
}
return uniqueStr.toString();
}
J'ai écrit un morceau de code pour résoudre le problème ..__ J'ai vérifié avec certaines valeurs, j'ai obtenu la sortie requise.
Remarque: cela prend du temps.
static void removeDuplicate(String s) {
char s1[] = s.toCharArray();
Arrays.sort(s1); //Sorting is performed, a to z
//Since adjacent values are compared
int myLength = s1.length; //Length of the character array is stored here
int i = 0; //i refers to the position of original char array
int j = 0; //j refers to the position of char array after skipping the duplicate values
while(i != myLength-1 ){
if(s1[i]!=s1[i+1]){ //Compares two adjacent characters, if they are not the same
s1[j] = s1[i]; //if not same, then, first adjacent character is stored in s[j]
s1[j+1] = s1[i+1]; //Second adjacent character is stored in s[j+1]
j++; //j is incremented to move to next location
}
i++; //i is incremented
}
//the length of s is i. i>j
String s4 = new String (s1); //Char Array to String
//s4[0] to s4[j+1] contains the length characters after removing the duplicate
//s4[j+2] to s4[i] contains the last set of characters of the original char array
System.out.println(s4.substring(0, j+1));
}
N'hésitez pas à exécuter mon code avec vos entrées. Merci.
Une autre solution semble être la plus concise à ce jour:
private static String removeDuplicates(String s)
{
String x = new String(s);
for(int i=0;i<x.length()-1;i++)
x = x.substring(0,i+1) + (x.substring(i+1)).replace(String.valueOf(x.charAt(i)), "");
return x;
}
Je résous un exercice similaire du livre: craquer l’interview de codage En utilisant la récursivité.
package crackingcodeinterview;
public class Exercise {
static String textString = "this is a random text of example!@#$%^(^452464156";
public static void main(String[] args) {
filterLetters(0, "");
}
public static void filterLetters(int position, String letters) {
if (position != textString.length()) {
boolean p = false;
for (int i = 0; i < letters.length(); i++) {
if (letters.charAt(i) == textString.charAt(position)) {
p = true;
break;
}
}
if (!p) {
letters += textString.charAt(position);
}
position++;
filterLetters(position, letters);
} else {
System.out.println(letters);
}
}
}
Autre solution utilisant la sous-chaîne et la récursivité
public class MyClass {
public static void main(String args[]) {
getUnicLetter("esta es una cadena con letras repetidas","");
}
public static String getUnicLetter(String originalWord,String finalWord){
if(originalWord.isEmpty()) return null;
System.out.print(finalWord);
return getUnicLetter(originalWord.replace(originalWord.substring(0,1),""),finalWord.contains(originalWord.substring(0,1)) ? "" : originalWord.substring(0,1));
}
}
public class RemoveCharsFromString {
static String testcase1 = "No, I am going to Noida";
static String testcase2 = "goings";
public static void main(String args[])throws StringIndexOutOfBoundsException{
RemoveCharsFromString testInstance= new RemoveCharsFromString();
String result = testInstance.remove(testcase1,testcase2);
System.out.println(result);
}
//write your code here
public String remove(String str, String str1)throws StringIndexOutOfBoundsException
{ String result=null;
if (str == null)
return "";
try
{
for (int i = 0; i < str1.length (); i++)
{
char ch1=str1.charAt(i);
for(int j=0;j<str.length();j++)
{
char ch = str.charAt (j);
if (ch == ch1)
{
String s4=String.valueOf(ch);
String s5= str.replaceAll(s4, "");
str=s5;
}
}
}
}
catch(Exception e)
{
}
result=str;
return result;
}
}
package com.Java.exercise;
public class RemoveCharacter {
/**
* @param args
*/
public static void main(String[] args) {
RemoveCharacter rem = new RemoveCharacter();
char[] ch=rem.GetDuplicates("JavavNNNNNNC".toCharArray());
char[] desiredString="JavavNNNNNNC".toCharArray();
System.out.println(rem.RemoveDuplicates(desiredString, ch));
}
char[] GetDuplicates(char[] input)
{
int ctr=0;
char[] charDupl=new char[20];
for (int i = 0; i <input.length; i++)
{
char tem=input[i];
for (int j= 0; j < i; j++)
{
if (tem == input[j])
{
charDupl[ctr++] = input[j];
}
}
}
return charDupl;
}
public char[] RemoveDuplicates(char[] input1, char []input2)
{
int coutn =0;
char[] out2 = new char[10];
boolean flag = false;
for (int i = 0; i < input1.length; i++)
{
for (int j = 0; j < input2.length; j++)
{
if (input1[i] == input2[j])
{
flag = false;
break;
}
else
{
flag = true;
}
}
if (flag)
{
out2[coutn++]=input1[i];
flag = false;
}
}
return out2;
}
}
En utilisant guava, vous pouvez faire quelque chose comme Sets.newHashSet(charArray).toArray();
Si vous n’utilisez aucune bibliothèque, vous pouvez toujours utiliser new HashSet<Char>()
et ajouter votre tableau char
à cet emplacement.
Une version améliorée pour l'utilisation de bitmask pour gérer 256 caractères:
public static void removeDuplicates3(char[] str)
{
long map[] = new long[] {0, 0, 0 ,0};
long one = 1;
for (int i = 0; i < str.length; i++)
{
long chBit = (one << (str[i]%64));
int n = (int) str[i]/64;
if ((map[n] & chBit ) > 0) // duplicate detected
str[i] = 0;
else // add unique char as a bit '1' to the map
map[n] |= chBit ;
}
// get rid of those '\0's
int wi = 1;
for (int i=1; i<str.length; i++)
{
if (str[i]!=0) str[wi++] = str[i];
}
// setting the rest as '\0'
for (;wi<str.length; wi++) str[wi] = 0;
}
Résultat: "## 1 !! ASDJasanwAaw.,; ..] [ [] == - 0" ==> "# 1! ASDJasnw.,;] [= - 0" (guillemets doubles non inclus)
public class StringRedundantChars {
/**
* @param args
*/
public static void main(String[] args) {
//initializing the string to be sorted
String sent = "I love painting and badminton";
//Translating the sentence into an array of characters
char[] chars = sent.toCharArray();
System.out.println("Before Sorting");
showLetters(chars);
//Sorting the characters based on the ASCI character code.
Java.util.Arrays.sort(chars);
System.out.println("Post Sorting");
showLetters(chars);
System.out.println("Removing Duplicates");
stripDuplicateLetters(chars);
System.out.println("Post Removing Duplicates");
//Sorting to collect all unique characters
Java.util.Arrays.sort(chars);
showLetters(chars);
}
/**
* This function prints all valid characters in a given array, except empty values
*
* @param chars Input set of characters to be displayed
*/
private static void showLetters(char[] chars) {
int i = 0;
//The following loop is to ignore all white spaces
while ('\0' == chars[i]) {
i++;
}
for (; i < chars.length; i++) {
System.out.print(" " + chars[i]);
}
System.out.println();
}
private static char[] stripDuplicateLetters(char[] chars) {
// Basic cursor that is used to traverse through the unique-characters
int cursor = 0;
// Probe which is used to traverse the string for redundant characters
int probe = 1;
for (; cursor < chars.length - 1;) {
// Checking if the cursor and probe indices contain the same
// characters
if (chars[cursor] == chars[probe]) {
System.out.println("Removing char : " + chars[probe]);
// Please feel free to replace the redundant character with
// character. I have used '\0'
chars[probe] = '\0';
// Pushing the probe to the next character
probe++;
} else {
// Since the probe has traversed the chars from cursor it means
// that there were no unique characters till probe.
// Hence set cursor to the probe value
cursor = probe;
// Push the probe to refer to the next character
probe++;
}
}
System.out.println();
return chars;
}
}
public class RemoveRepeatedCharacters {
/**
* This method removes duplicates in a given string in one single pass.
* Keeping two indexes, go through all the elements and as long as subsequent characters match, keep
* moving the indexes in opposite directions. When subsequent characters don't match, copy value at higher index
* to (lower + 1) index.
* Time Complexity = O(n)
* Space = O(1)
*
*/
public static void removeDuplicateChars(String text) {
char[] ch = text.toCharArray();
int i = 0; //first index
for(int j = 1; j < ch.length; j++) {
while(i >= 0 && j < ch.length && ch[i] == ch[j]) {
i--;
j++;
System.out.println("i = " + i + " j = " + j);
}
if(j < ch.length) {
ch[++i] = ch[j];
}
}
//Print the final string
for(int k = 0; k <= i; k++)
System.out.print(ch[k]);
}
public static void main(String[] args) {
String text = "abccbdeefgg";
removeDuplicateChars(text);
}
}
Question: Supprimer les caractères en double dans une chaîne Méthode 1: (Python)
import collections
a = "GiniGinaProtijayi"
aa = collections.OrderedDict().fromkeys(a)
print(''.join(aa))
Méthode 2: (Python)
a = "GiniGinaProtijayi"
list = []
aa = [ list.append(ch) for ch in a if ch not in list]
print( ''.join(list))
En Java:
class test2{
public static void main(String[] args) {
String a = "GiniGinaProtijayi";
List<Character> list = new ArrayList<>();
for(int i = 0 ; i < a.length() ;i++) {
char ch = a.charAt(i);
if( list.size() == 0 ) {list.add(ch);}
if(!list.contains(ch)) {list.add(ch) ;}
}//for
StringBuffer sbr = new StringBuffer();
for( char ch : list) {sbr.append(ch);}
System.out.println(sbr);
}//main
}//end
Cette fonction supprime les doublons de la chaîne inline. J'ai utilisé C # comme langage de codage et les doublons sont supprimés en ligne
public static void removeDuplicate(char[] inpStr)
{
if (inpStr == null) return;
if (inpStr.Length < 2) return;
for (int i = 0; i < inpStr.Length; ++i)
{
int j, k;
for (j = 1; j < inpStr.Length; j++)
{
if (inpStr[i] == inpStr[j] && i != j)
{
for (k = j; k < inpStr.Length - 1; k++)
{
inpStr[k] = inpStr[k + 1];
}
inpStr[k] = ' ';
}
}
}
Console.WriteLine(inpStr);
}
public static void main(String[] args) {
char[] str = { 'a', 'b', 'a','b','c','e','c' };
for (int i = 1; i < str.length; i++) {
for (int j = 0; j < i; j++) {
if (str[i] == str[j]) {
str[i] = ' ';
}
}
}
System.out.println(str);
}
/* program to remove the duplicate character in string */
/* Author senthilkumar M*/
char *dup_remove(char *str)
{
int i = 0, j = 0, l = strlen(str);
int flag = 0, result = 0;
for(i = 0; i < l; i++) {
result = str[i] - 'a';
if(flag & (1 << result)) {
*/* if duplicate found remove & shift the array*/*
for(j = i; j < l; j++) {
str[j] = str[j+1];
}
i--;
l--; /* duplicates removed so string length reduced by 1 character*/
continue;
}
flag |= (1 << result);
}
return str;
}
public class RemoveDuplicateInString {
public static void main(String[] args) {
String s = "ABCDDCA";
RemoveDuplicateInString rs = new RemoveDuplicateInString();
System.out.println(rs.removeDuplicate(s));
}
public String removeDuplicate(String s) {
String retn = null;
boolean[] b = new boolean[256];
char[] ch = s.toCharArray();
for (int i = 0; i < ch.length; i++) {
if (b[ch[i]]) {
ch[i]=' ';
}
else {
b[ch[i]] = true;
}
}
retn = new String(ch);
return retn;
}
}
Eh bien, je suis venu avec la solution suivante. En gardant à l’esprit que S et s ne sont pas des doublons. De plus, je n'ai qu'une seule valeur codée en dur. Mais le code fonctionne parfaitement.
public static String removeDuplicate (String str) {
StringBuffer rev = new StringBuffer();
rev.append(str.charAt(0));
for(int i=0; i< str.length(); i++)
{
int flag = 0;
for(int j=0; j < rev.length(); j++)
{
if(str.charAt(i) == rev.charAt(j))
{
flag = 0;
break;
}
else
{
flag = 1;
}
}
if(flag == 1)
{
rev.append(str.charAt(i));
}
}
return rev.toString();
}
String s = "Javajk";
List<Character> charz = new ArrayList<Character>();
for (Character c : s.toCharArray()) {
if (!(charz.contains(Character.toUpperCase(c)) || charz
.contains(Character.toLowerCase(c)))) {
charz.add(c);
}
}
ListIterator litr = charz.listIterator();
while (litr.hasNext()) {
Object element = litr.next();
System.err.println(":" + element);
} }
cela supprimera le doublon si le personnage est présent dans les deux cas.
Cela serait beaucoup plus facile si vous parcouriez simplement le tableau et que vous ajoutiez tous les nouveaux caractères à une liste, puis que vous revoyiez cette liste.
Avec cette approche, vous devez remanier le tableau au fur et à mesure que vous le parcourez et le redimensionner éventuellement à la taille appropriée à la fin.