1

我试着把一个词拆开,然后把它混在 12 个随机字母中。

有谁知道为什么这段代码只能工作 5 次中的 3 次?当它不起作用时,它只缺少应该存在的 1 或 2 个字母。

谢谢

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; }
4

2 回答 2

2

在这个循环中,

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

r.nextInt(characters.length())考虑在两次不同的迭代中返回相同的数字时会发生什么。

Math.random() * rl.length在另一个循环中类似。

数组混洗器需要跟踪哪些元素已经过混洗

假设我们从以下开始:

a b c d e f

考虑洗牌数组的第一个元素。它需要从集合{a, b, c, d, e, f}中以每个元素的 1/6 概率随机选取。

洗牌数组的第二个元素需要从{a, b, c, d, e, f} - {shuffled[0]}原始数组的所有元素中随机挑选,减去第一个位置挑选的元素,这次是 1/5 的概率。

同样,第三个元素来自{a, b, c, d, e, f} - {shuffled[0], shuffled[1]},每个都有 1/4 的概率,依此类推。

如果您正在就地改组数组,那么您可以通过交换来移动元素,这最终会自动跟踪剩余的元素。说e是第一选择。看看如果我们交换a和会发生什么e

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

由于选择的元素被移动到索引 0,所有剩余的元素现在都在索引 1 到 5 中。现在只需要从索引 1 到 5 之间选择下一个元素。

假设b下一个被选中,因此它与自身交换:

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

不,我们在索引 2 到 5 处有剩余元素。算法可以以这种方式继续运行,直到索引 4,此时整个数组将被打乱。因为元素交换让您可以轻松地跟踪剩余的内容,所以更容易就地打乱数组

如果您查看 JDK 源代码,您会发现它Collections.shuffle()做了同样的事情,只是进行了一次优化

于 2012-04-19T01:25:44.630 回答
1

我不确定你的问题是什么,但我会冒险猜测。char 数组 text[] 的长度为 12。假设传入的单词小于那个?

当您遍历 wrd 并将字符放入 rl 时,不能保证您不会覆盖您之前放入的字母。

于 2012-04-19T01:31:43.460 回答