隨機取數問題

2021-08-26 11:16:07 字數 1263 閱讀 9573

問題描述:

輸入兩個正整數m和n(m<=n),輸出乙個有m個隨機數組成的隨機列表,這些隨機數的範圍時0~n-1,並且每乙個整數只能出現一次。

方法一:o(n)

整體來說,從n個整數中隨機選擇m個不重複整數,選擇每乙個整數的概率都是m/n,因此在進行選擇時,需要保證每個整數被選擇的概率是m/n就能滿足問題要求。

實現**如下:

if(rand()%remaining < select )能夠保證選擇每個元素的概率時m/n。

例如,從5個元素中選擇2個元素,

(1)在選擇第乙個元素時:需滿足rand()%5 < 2,這時候選擇元素的概率時2/5。

(2)在選擇第二個元素時:需滿足rand()%4<1,這時候選擇該元素的概率也是2/5 = 2/5 * 1/4 + 3/5 * 2/4 。 6

voidrand_select(

intn,

intm)//m<=n 7

19remaining--;

20}

21printf(

"/n");

22}

方法二:0(mlogm)

直接選擇m個範圍在0~n-1的隨機數,然後插入到某種資料結構中,比如二分查詢數等,可以實現logm的效率。這裡使用stl 中的set。

**如下:

27voidrand_select(

intn,

intm) 28

36set<

int>::iteratorit=mset.begin();

37while(it!=mset.end()) 38

42cout<

43}

但是這個演算法存在的缺陷是:當m和m很大時,可能會產生許多相同的隨機值,在進行mset插入時出現浪費,一種防止這種消耗的做法見《程式設計珠璣》問題12.9答案。

方法三:

這個方法是通過用隨機的方法弄亂乙個陣列來實現,然後排序陣列並輸出前m個。弄亂陣列a[0~n-1]的方法是(偽碼):

for(int i = 0;iswap(a[i],rand(i,n-1))。

在這裡,由於我們只需要去m個隨機數,故可以只弄亂陣列的前m個元素,然後排序陣列的前m個元素並輸出,實現**如下:

52voidrand_select(

intn,

intm) 53

63//sort(a,a+m);//

排序前m

個元素64

for(i=0;i

65cout<"";

66cout<

67}

隨機取數問題

問題描述 輸入兩個正整數m和n m n 輸出乙個有m個隨機數組成的隨機列表,這些隨機數的範圍時0 n 1,並且每乙個整數只能出現一次。方法一 o n 整體來說,從n個整數中隨機選擇m個不重複整數,選擇每乙個整數的概率都是m n,因此在進行選擇時,需要保證每個整數被選擇的概率是m n就能滿足問題要求。...

ojbc 取隨機數

隨機數的使用 1 arc4random 比較精確不需要生成隨機種子 使用方法 通過arc4random 獲取0到x 1之間的整數的 如下 int value arc4random x 獲取1到x之間的整數的 如下 int value arc4random x 1 2 ccrandom 0 1 coc...

PHP 取隨機數

假設 有四個選項 a 佔 10 b佔20 c佔30 d 佔 40 原理就是現獲取隨機數,然後找區間。當然了,選項的數量可以任意。目前預設是 總和是 100 如果需要別的數,修改 隨機數的範圍即可。這個演算法,比較簡單,效率也還算高。當然因為是 rand 所以產生的是偽隨機數,不是真正意義上的隨機,能...