2010-07-23 3 views
13

Comment mélanger les caractères dans une chaîne (par exemple, bonjour pourrait être ehlol ou lleoh ou ...). Je ne veux pas utiliser la méthode Collections.shuffle(...), y a-t-il quelque chose de plus simple?Comment mélanger des caractères dans une chaîne

+6

ne pas vouloir, ou votre conférencier vous a dit de ne pas? –

+2

Je doute qu'il y ait quelque chose de plus simple que quelque chose qui est déjà disponible pour vous d'utiliser ... (au moins dans ce cas) – npinti

+0

ne veut pas utiliser shuffle – user339108

Répondre

25

Je ne connais rien de plus simple. Mais vous pouvez utiliser la fonctionnalité Math.rand() pour générer un nombre aléatoire dans la plage de la longueur du caractère sans remplacer et qui vous donnerait une sortie brassé

public class Shuffle { 
    public static void main(String[] args) { 
     Shuffle s = new Shuffle(); 
     s.shuffle("hello"); 

    } 
    public void shuffle(String input){ 
     List<Character> characters = new ArrayList<Character>(); 
     for(char c:input.toCharArray()){ 
      characters.add(c); 
     } 
     StringBuilder output = new StringBuilder(input.length()); 
     while(characters.size()!=0){ 
      int randPicker = (int)(Math.random()*characters.size()); 
      output.append(characters.remove(randPicker)); 
     } 
     System.out.println(output.toString()); 
    } 
} 
/* 
Sample outputs 
hlleo 
llheo 
leohl 
lleho 
*/ 
0

Vous pouvez itérer sur tous les personnages, la comparaison de chaque un avec le suivant. Ensuite, si Math.rand()> 0.5 échange ce caractère avec le suivant, sinon, passe au caractère suivant.

1

Par exemple:

static String shuffle(String text){ 
    if (text.length()<=1) 
     return text; 

    int split=text.length()/2; 

    String temp1=shuffle(text.substring(0,split)); 
    String temp2=shuffle(text.substring(split)); 

    if (Math.random() > 0.5) 
     return temp1 + temp2; 
    else 
     return temp2 + temp1; 
}  
3
class ShuffleString 
{ 

    public static String shuffle(String s) 
    { 

     String shuffledString = ""; 

     while (s.length() != 0) 
     { 
      int index = (int) Math.floor(Math.random() * s.length()); 
      char c = s.charAt(index); 
      s = s.substring(0,index)+s.substring(index+1); 
      shuffledString += c; 
     } 

     return shuffledString; 

    } 

} 


public class foo{ 
    static public void main(String[] args) 
    { 

     String test = "hallo"; 
     test = ShuffleString.shuffle(test); 
     System.out.println(test); 
    } 
} 

Sortie: ahlol

10

Pas d'excellentes performances, mais tout à fait lisible à mon avis:

public static String shuffleString(String string) 
{ 
    List<String> letters = Arrays.asList(string.split("")); 
    Collections.shuffle(letters); 
    String shuffled = ""; 
    for (String letter : letters) { 
    shuffled += letter; 
    } 
    return shuffled; 
} 
0

le code est ici qui ne nécessite ni récursion, ni convertir en une collection.

public static String shuffle(String string) { 
    StringBuilder sb = new StringBuilder(string.length()); 
    double rnd; 
    for (char c: string.toCharArray()) { 
     rnd = Math.random(); 
     if (rnd < 0.34) 
      sb.append(c); 
     else if (rnd < 0.67) 
      sb.insert(sb.length()/2, c); 
     else 
      sb.insert(0, c); 
    }  
    return sb.toString(); 
} 
1

Vous ne savez pas pourquoi vous ne souhaitez pas utiliser shuffle, sauf pour l'école.

Et si vous êtes concerné par la performance, vous ne pouvez certainement pas utiliser une solution qui concatène les chaînes avec "+".

est ici la solution la plus compacte que je pouvais trouver:

public static String shuffle(String string) { 
    if (StringUtils.isBlank(string) { 
     return string; 
    } 

    final List<Character> randomChars = new ArrayList<>(); 
    CollectionUtils.addAll(randomChars, ArrayUtils.toObject(string.toCharArray())); 
    Collections.shuffle(randomChars); 
    return StringUtils.join(randomChars, ""); 
} 
5

Que diriez-vous ceci:

public static String shuffle(String text) { 
    char[] characters = text.toCharArray(); 
    for (int i = 0; i < characters.length; i++) { 
     int randomIndex = (int)(Math.random() * characters.length); 
     char temp = characters[i]; 
     characters[i] = characters[randomIndex]; 
     characters[randomIndex] = temp; 
    } 
    return new String(characters); 
} 
0
 String shuffled; 
     do { 
      shuffled = Stream.of(text.split("")).sorted((o1, o2) -> ThreadLocalRandom.current().nextInt(3) - 1).collect(Collectors.joining()); 
     }while(shuffled.equals(text)); 
+0

Cool en effet mais cassé, parce qu'un 'comparateur 'doit revenir le même résultat pour une paire donnée de chaînes, sinon vous avez un problème avec la méthode 'sort (...)' et pourriez obtenir une "Méthode de comparaison qui viole son contrat général!" à partir du TimSort interne. –

0

Quel problème gênant. J'ai finalement fini avec ceci:

import java.util.Collections; 
import com.google.common.primitives.Chars; 
import org.apache.commons.lang3.StringUtils; 

String shuffle(String s) { 
    List<Character> chars = Chars.asList(s.toCharArray()); 
    Collections.shuffle(chars); 
    return StringUtils.join(chars.stream().toArray()); 
} 

Oui, deux bibliothèques :)

0

Si vous voulez continuer à restaurer plus tard le String d'origine, essayez quelque chose comme ceci:

public static class ShuffledString 
{ 
    private List<Integer> indices; 
    private String string; 

    public ShuffledString(List<Integer> indices, String string) 
    { 
     this.indices = indices; 
     this.string = string; 
    } 

    public List<Integer> getIndices() 
    { 
     return indices; 
    } 

    public String getRegularString() 
    { 
     StringBuilder stringBuilder = new StringBuilder(); 

     for (int stringIndex = 0; stringIndex < indices.size(); stringIndex++) 
     { 
      int characterIndex = indices.indexOf(stringIndex); 
      stringBuilder.append(string.charAt(characterIndex)); 
     } 

     return stringBuilder.toString(); 
    } 
} 

public static ShuffledString shuffle(String input) 
{ 
    List<Integer> indices = new ArrayList<>(); 

    StringBuilder output = new StringBuilder(input.length()); 
    while (indices.size() < input.length()) 
    { 
     int randomIndex; 

     while (indices.contains(randomIndex = (int) (Math.random() * input.length()))) 
     { 

     } 

     indices.add(randomIndex); 
     output.append(input.charAt(randomIndex)); 
    } 

    return new ShuffledString(indices, output.toString()); 
} 
Questions connexes