我有一个int向量,例如int[] A = {6, 1, 5, 3, 4, 2}
,我需要在三个步骤中随机选取两个不同的元素,每个步骤应该从其他步骤中提取不同的元素。
例如:
我尝试这样做,但我多次失败。我真的很感激任何帮助。 这是我的最后一段代码。
public class T8 {
public static void main(String[] args) {
int n=5, d=2, r, i, j;
int[] B = new int [d];
Random rand=new Random();
System.out.println("d = "+d);
Integer[] A = {10,12,3,4,5};
List<Integer> list = new ArrayList<Integer>(Arrays.asList(A));
for(j=0; j<d; j++){
r = rand.nextInt(n);
B[j] = A[r];
System.out.print(B[j]+" ");
list.remove(r);
A = list.toArray(new Integer[0]);
n=n-1;
}
System.out.println("");
for(j=0; j<n; j++){
System.out.print(A[j]+" ");
}
}
}
答案 0 :(得分:0)
非最佳方法:您可以使用random.nextInt并且每次生成随机数时检查它是否唯一,如果不生成新的随机索引。 E.g。
import java.util.HashSet;
import java.util.Random;
import java.util.Set;
public class RandomPicker {
public static void main(String[] args) {
int[] arr = {6, 1, 5, 3, 4, 2};
Random random = new Random();
Set<Integer> randoms = new HashSet<>();
while (arr.length != randoms.size()) {
int i = nextRandomIndex(arr, random, randoms);
int j = nextRandomIndex(arr, random, randoms);
System.out.printf("%d,%d\n", arr[i], arr[j]);
}
}
private static int nextRandomIndex(int[] arr, Random random, Set<Integer> randoms) {
int i = random.nextInt(arr.length);
while (randoms.contains(i)) {
i= random.nextInt(arr.length);
}
randoms.add(i);
return i;
}
}
可能的输出
4,1
6,3
5,2
更好的方法是对数组进行混洗,然后对其进行迭代(如果您不想修改数组,则将原始数组的副本传递给shuffle方法)。 E.g。
import java.util.Arrays;
import java.util.Random;
public class RandomPicker {
public static void main(String[] args) {
int[] arr = {6, 1, 5, 3, 4, 2};
int[] copy = Arrays.copyOf(arr, arr.length);
shuffle(copy);
int index = 0;
for (int i = 0; i < arr.length / 2; i++) {
System.out.printf("%d, %d\n",copy[index], copy[++index]);
}
}
private static void shuffle(int[] arr)
{
int index;
int temp;
Random rand = new Random();
int i = arr.length - 1;
while ( i > 0)
{
index = rand.nextInt(i + 1);
temp = arr[index];
arr[index] = arr[i];
arr[i] = temp;
i--;
}
}
}
答案 1 :(得分:0)
有许多方法可以做到这一点:
将数组元素复制到List
中,然后从列表中随机删除元素。
使用(弱)伪随机数生成器以可预测的方式遍历所有索引。
创建之前返回的所有元素的HashSet
。
使用shuffle
方法就地对输入数组进行随机播放,然后从索引0
开始一次返回一个元素,直到达到length - 1
。
如果您无法更改输入数组,则创建一个填充了值0
到length - 1
的数组,随机播放该数组,然后使用其遍历该数组值作为第一个数组的索引。
@ sol4me的解决方案(上面是3.和5.的混合)有一个有趣的属性。计算行为是概率性的:
当你到达序列的末尾时,找到并返回一个之前没有使用的索引所花费的时间会增长,并且会惊恐地发现#34;
理论上最坏情况的行为是nextRandomIndex
永远不会终止。 (只有当您的随机数生成器有偏差时才会发生这种情况。)
对于&#34;完美&#34;随机数生成器,nextRandomIndex
执行的迭代次数是有限的,但我们不能在其上设置上限。
对于伪随机数生成器,生成器的循环长度是迭代次数的上限。
您尝试的解决方案接近我建议的第一个解决方案。但有一个问题是
List<Integer> list = new ArrayList<Integer>(Arrays.asList(A));
正在创建一个&#34;视图&#34;到无法更改长度的数组。如果您创建ArrayList
然后将数组元素复制到列表中,则无法获得您在remove
中看到的例外情况。
另一个问题是:
A = list.toArray(new Integer[0]);
非常低效。没有必要将列表转换回数组。请保留下次列表。