問題描述:
輸入兩個正整數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 所以產生的是偽隨機數,不是真正意義上的隨機,能...