寻找关于java中的shuffle和cryptogram问题的一些帮助。
首先,我试图随机调整一个数组,但我在混洗数组中继续得到两个相同的值。
这是代码:)
public static void shuffle (char[] characterArray) {
Random generator = new Random(12345);
for (int i= 0; i<characterArray.length ; i++) {
int numberChoosen = generator.nextInt(characterArray.length);
System.out.print((characterArray[numberChoosen]));
}
}
正如您所看到的,对于{A,B,C,D}
的characterArray,代码生成一个看起来像{B,C,D,D}
的混洗数组....为什么它为每个字母生成两个D而不是1个字母原始阵列?
谢谢! :)
答案 0 :(得分:2)
使用Random并不能防止多次输入。如果你想简单地随机化数组的顺序,你可能会建议生成一个新数组,用旧数组中的条目填充它 - 一次从旧数组中删除一个条目以创建新数组。 / p>
由于Java中的数组大小不可变,您可能需要使用一些额外的或备用的数据结构来跟踪已经返回的条目。
Random shuffling of an array提供了许多可用于执行此操作的方法 - 包含源代码。
您可以尝试这样的事情:
public static void shuffle(char[] characterArray){
final List<Character> charList = new ArrayList<>(characterArray.length);
for(final char c : characterArray){
charList.add(c);
}
Collections.shuffle(charList);
for(final char c : charList){
System.out.print(c);
}
}
单参数Collections.shuffle
调用在内部创建并使用new Random()
。但是,如果你必须使用&#34; /显示使用Random类(或使用替代的随机源):
public static void shuffle(char[] characterArray){
final Random generator = new Random(12345);
final List<Character> charList = new ArrayList<>(characterArray.length);
for(final char c : characterArray){
charList.add(c);
}
Collections.shuffle(charList, generator);
for(final char c : charList){
System.out.print(c);
}
}
现在,如果你在这里寻找不可预测的输出,我就不会使用具有常数值的单参数Random构造函数。
或者,您可以在不调用Collections.shuffle
的情况下自行完成类似操作的方法。自己查看Collections.shuffle
的源代码也可能具有教育意义。
答案 1 :(得分:1)
用于混洗数组的标准算法是Fisher-Yates shuffle,也称为Knuth的“算法P”。除非你有充分的理由不使用它,否则请使用Fisher-Yates。
如果您正在查看加密用途,那么您将需要使用加密安全随机数生成器,例如Java SecureRandom
。不要使用标准的不安全RNG,这些RNG在统计上很好,但在加密方面非常不安全。