2013-12-12 54 views
0

我想從我的數組中獲得n個獨特的隨機元素。在數組中獲取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. 
} 

碰撞比比皆是,特別是在小陣列上。

什麼是解決這個特別優雅的方法?

+4

你爲什麼標記3種不同的語言? – Marty

回答

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 
} 
0

使用套件可能是最好的事情。

如果你想要數組中的唯一元素(即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; 
} 
+0

它有一個很大的開銷,有另一個列表來存儲已插入的值,然後在每次插入過程中也有一個檢查。 「集合」是爲了這種目的。 – SudoRahul

+0

@ R.J真,改變了。 – Burkhard

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]); 
     } 
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. 
    } 
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 
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); 
} 

在消除隨機因素這樣,我從剩下隨機選取,並不必擔心隨機數/指數法的衝突。