IceSteve
IceSteve

Reputation: 577

Trying to mix a strings characters in random letters

Im trying to take a word, break it apart, and mix it within 12 random letters.

Does anyone see why this code only works maybe 3 out of 5 times? When it doesn't work, its only missing 1 or 2 of the letters that should be there.

Thank you

public static String MixWordWithLetters(String word) {
Random r = new Random();

String characters = "abcdefghijklmnopqrstuvwxyz";  
char[] text = new char[12];
for (int i = 0; i < 12; i++)
{
    text[i] = characters.charAt(r.nextInt(characters.length()));
}
String randomletters = new String(text);

char[] wrd = word.toCharArray();
char[] rl = randomletters.toCharArray();

for (int i = 0; i < wrd.length; i++) {
    int rand = (int) (Math.random() * rl.length);
    rl[rand] = wrd[i] ;
}

 String WordMixed = new String(rl);
return WordMixed; }

Upvotes: 1

Views: 2652

Answers (2)

oksayt
oksayt

Reputation: 4365

In this loop,

for (int i = 0; i < 12; i++) 
{
    text[i] = characters.charAt(r.nextInt(characters.length()));
}

Consider what happens when r.nextInt(characters.length()) returns the same number in two different iterations.

Similarly for Math.random() * rl.length in the other loop.

An array shuffler needs to track which elements are already shuffled

Let's say we start with:

a b c d e f

Consider the first element of the shuffled array. It needs to be randomly picked from the set {a, b, c, d, e, f} with 1/6 probability for each element.

The second element of the shuffled array needs to be randomly picked from {a, b, c, d, e, f} - {shuffled[0]} i.e. all elements of the original array, minus what was picked for the first position, this time with 1/5 probability.

Similarly, the third element comes from {a, b, c, d, e, f} - {shuffled[0], shuffled[1]}, with 1/4 probability on each, and so on.

If you're shuffling an array in-place, then you can move elements around by swapping, which ends up keeping track of the remaining elements automatically. Say e was the first choice. See what happens if we swap a and e:

e b c d a f
^ . . . . .

Since the picked element was moved to index 0, all remaining elements are now in indices 1 through 5. Now the next element just needs to be picked from between indices 1 to 5.

Let's say b is picked next, thus it's swapped with itself:

e b c d a f
^ ^ . . . .

No we have the remaining element at indices 2 to 5. The algorithm can keep going in this fashion until index 4, at which point the entire array will be shuffled. Because element swapping lets you easily keep track of what's remaining, it's easier to shuffle an array in-place.

If you look into the JDK source, you'll see that Collections.shuffle() does the same thing, with one optimization.

Upvotes: 2

Phil Freihofner
Phil Freihofner

Reputation: 7910

I'm not sure what your question is, but I will venture a guess. The char array text[] is 12 long. The incoming word is assumed to be less than that?

When you loop through the wrd and put characters into rl, there is no guarantee that you won't overwrite a letter you put there previously.

Upvotes: 1

Related Questions