我想从我的数组中获取n个独特的随机元素。
例如:
if n = 4;
我想随机获取
array[0], array[3], array[7], array[2]
问题是得到一个随机整数会导致容易碰撞(伪代码):
for n times
{
r = generateRandomInteger within n-1
list.push(array[r]); //array[r] can be the same.
}
碰撞比比皆是,特别是在小阵列上。
解决这个问题的方法是什么?
答案 0 :(得分:1)
您可以使用Set
代替List
来消除重复项。因此,您还需要更改循环条件。像这样的东西
while set.size() is less than n
{
r = generateRandomInteger within n-1
set.add(array[r]); //if its the same, it won't be added to the set and the size won't increase
}
答案 1 :(得分:1)
你可以这样做:我建议你先使用它。
首先使用SET:
for n times
{
r = generateRandomInteger within n-1
// you can use SET instead of LIST cause SET not allow duplication.
set.push(array[r]); //array[r] can be the same.
}
其次使用LIST:
for n times
{
r = generateRandomInteger within n-1
if(!list.contains(array[r]))
list.push(array[r]); //array[r] can be the same.
}
答案 2 :(得分:0)
使用Set可能是最好的选择。
如果你想要数组中的唯一元素(即array []的值),那么使用R.J的解决方案。如果你想要独特的指数:
while set.size() is less than n
{
r = generateRandomInteger within n-1
set.add(r);
}
foreach(r: set)
{
list.add(array[r]);
}
如果你想要更多的元素然后是数组的长度,请小心,因为你会得到一个无限循环:
if(n>array.length)
{
print("Cannot get more then ... elements!");
return null;
}
答案 3 :(得分:0)
您可以将所有随机整数添加到列表中并生成新的随机数,直到列表不包含此随机int。这不是最好的表现,但它确实有效。
List<Integer> randoms = new ArrayList<Integer>()
for(int i=0; i<n;i++){
while(randoms.contains(r)) {
r = Random.nextInt(array.length-1);
}
randoms.add(r);
list.push(array[r]);
}
答案 4 :(得分:0)
int n = 4;
for (int i = 0; i < n; i++)
{
int index = RandomBetweenInclusive(i, array.length() - 1); //made up function
int temp = array[i];
array[i] = array[index];
array[index] = array[i];
}
//array values between indices 0 and n-1 will be random and unique values of array
答案 5 :(得分:0)
我在这种情况下通常做的是将我想要选择的所有项目推送到集合
var selectFrom = original.clone; // or build array
var selected = new collection;
然后我去删除selectFrom集合中的随机元素
for (i = 0; i < toSelect; i++)
{
var rndItem = selectFrom[ rand() * selectFrom.length ];
selected.add(rndItem);
selectFrom.remove(rndItem);
}
这样我就可以从剩下的内容中随机选择,而不必担心随机数/索引中的冲突。