寫一個函數,隨機地從大小爲n的數組中選取m個整數。要求每一個元素被選中的機率相等。

隨機地從大小替n的數組中選取m個整數

www.MyException.Cn  網友分享於:2013-10-08  瀏覽:30次java

隨機地從大小爲n的數組中選取m個整數算法

問題:寫一個函數,隨機地從大小爲n的數組中選取m個整數。要求每一個元素被選中的機率相等。數組

 

分析:這道題目和隨機洗牌算法相似,只須要隨機選取1個元素, 而後在剩下的元素裏面隨機選取下一個元素,不斷這樣操做便可。app

這樣作能保證每一個元素選中的機率同樣嗎?也就是選中每一個元素的機率都是1/n? 答案是YES,讓咱們來作一下簡單的計算。dom

  • 選第1個元素:在n箇中隨機選,所以機率爲1/n函數

  • 選第2個元素:在剩下的n-1箇中隨機選:1/(n-1),因爲第1次沒有選中它, 而是在另外n-1箇中選:(n-1)/n,所以機率爲:(n-1)/n * 1/(n-1) = 1/nspa

  • 選第3個元素:同上:(n-1)/n * (n-2)/(n-1) * 1/(n-2) = 1/n.net

    。。。。。blog

所以,按照這種方法選取k個元素,每一個元素都是以1/n的機率被選出來的ip

 

基本思想:

                首先在下標0---n之間隨機生成一個下標,將這個下標對應的數和數組的第一個數交換位置;而後從小標1----n之間隨機生成一個數,將下標對應的

數和數組的第二個數交換位置。依次這樣下去,知道找出m個數。

[java] view plain copy

 

  1. public class RandomM {  
  2.   
  3.     public static void main(String[] args) {  
  4.         // TODO Auto-generated method stub  
  5.         int[] arr=new int[10];  
  6.         for(int i=0;i<10;i++){  
  7.             arr[i]=i;  
  8.         }  
  9.         for(int n: selectM(arr, 5)){  
  10.             System.out.println(n);  
  11.         }  
  12.     }  
  13.       
  14.     //從長度爲n的數組中隨機的選擇m個整數  
  15.     public static int[] selectM(int[] arr,int m){  
  16.         int len=arr.length;  
  17.         if(m>arr.length)  
  18.             throw new RuntimeException("xxxxx");  
  19.         int[] res=new int[m];  
  20.         for(int i=0;i<m;i++){  
  21.             int randomIndex=len-1-new Random().nextInt(len-i);  
  22.             res[i]=arr[randomIndex];  
  23.             int tmp=arr[randomIndex];  
  24.             arr[randomIndex]=arr[i];  
  25.             arr[i]=tmp;  
  26.         }  
  27.         return res;  
  28.     }  
  29.   
  30. }
相關文章
相關標籤/搜索