到目前为止,我的代码几乎都在努力工作。说明在方法之上。我遇到的唯一问题是Math.random();
多次调用时会重复。我想知道是否存在阻止Math.random();
重复自身的解决方案;
/**
* Apply an "efficient selection shuffle" to the argument.
* The selection shuffle algorithm conceptually maintains two sequences
* of cards: the selected cards (initially empty) and the not-yet-selected
* cards (initially the entire deck). It repeatedly does the following until
* all cards have been selected: randomly remove a card from those not yet
* selected and add it to the selected cards.
* An efficient version of this algorithm makes use of arrays to avoid
* searching for an as-yet-unselected card.
* @param values is an array of integers simulating cards to be shuffled.
*/
public static void selectionShuffle(int[] values) {
ArrayList<Integer> temp=new ArrayList<Integer>();
int size=52;
for(int j=0;j<size;j++){
/*int random=(int)(Math.random()*51);
temp.add(random);
values[j]=temp.get(j);*/
int random=(int)(Math.random()*51);
temp.add(values[random]);
values[j]=temp.get(j);
}
}
答案 0 :(得分:3)
如果你想要随机顺序的整数0-51而没有重复:
Collections.shuffle
根据birthday paradox,简单地使用(int) (52 * Math.random())
51次将几乎保证会重复某些数字(当然,有些数字会丢失)。
答案 1 :(得分:0)
据我所知,您认为Math.random正在“重复”,因为您总是选择0到51之间的新数字来添加到values
数组中。在您有机会选择这些数字之前,您将覆盖values
数组的早期部分。
考虑说明中概述的流程。如果您在每次迭代时从初始数组中选择一次,并将这些选择移动到新的temp
数组中,那么每次values
不应该变小?也许你并不总是想要一个0-51的随机数。
忽略所有告诉你不同方法进行洗牌的人。显然,你正在尝试实现编码实践所给出的算法。
答案 2 :(得分:0)
不确定您的问题是什么,但请尝试使用java.util.Random。
public static void selectionShuffle(int[] values)
{
ArrayList<Integer> temp=new ArrayList<Integer>();
Random randomGenerator = new Random();
int size=52;
for(int j=0;j<size;j++){
// If you wan to generate a random number up to a maximum value,
// use randomGenerator.nextInt(maximum) instead
int random = randomGenerator.nextInt() * 51;
temp.add(values[random]);
values[j]=temp.get(j);
}
}
答案 3 :(得分:0)
当数字是随机的时,每个数字都有相同的发生几率,而不管之前发生的事情。这意味着随机数必须能够重复,或者它们不再是真正随机的。
如果你想要一组数字,卡片,歌曲以随机顺序出现而不重复,这就叫做shuffle。注意:最后一个号码,卡片或歌曲根本不是随机的,因为它将是剩下的唯一一个。
使用随机序列,您甚至可以多次出现相同的数字。
http://vanillajava.blogspot.co.uk/2011/10/randomly-no-so-random.html
Random random = new Random(441287210);
for (int i = 0; i < 10; i++)
System.out.print(random.nextInt(10)+" ");
打印
1 1 1 1 1 1 1 1 1 1
和
Random random = new Random(-6732303926L);
for(int i = 0; i < 10; i++)
System.out.print(random.nextInt(10)+" ");
打印
0 1 2 3 4 5 6 7 8 9
答案 4 :(得分:0)
据我所知,您不希望Math.random()
多次返回一个数字。如果这是问题,我们要做的是允许Math.random()
返回它喜欢的任何内容,但我们只使用非重复的数字。
试试这个:
public static void selectionShuffle(int[] values) {
ArrayList<Integer> temp=new ArrayList<Integer>();
int size=52;
Integer a[]=new Integer[size];
for(int j=0;j<size;j++){
int random=(int)(Math.random()*51);
if(a.[random]==null) //to ensure that only unique nos. are used.
{
temp.add(values[random]);
values[j]=temp.get(j);
a.[random]=1;
// the above code will only be executed if `a[random]` is null
//ensures that this executes only when unique number is generated
}
else
{
j--;
//so that 52 iterations occur successfully. We don't want any iteration to go waste.
}
}
我使用了Integer
数组来确保使用唯一的数字。每次生成唯一编号时,我们都会将1
或其他整数分配给整数数组的特定索引。只有在a[]'s
生成的整数对应的索引处未设置random
值时,才会执行相关代码。
答案 5 :(得分:0)
你想在没有替换的情况下进行随机抽签,但是你已经实施了随机抽奖......
将牌放入52号阵列中,然后在第一次抽牌中执行以下操作:
(int)(Math.random()*51 + 1);
这给你一个介于1-52之间的随机数,比如你得到4,然后通过删除第四个元素来更新数组,留下你的大小为51的数组。然后进行第二次抽奖:
(int)(Math.random()*50 + 1);
等等......