在給定範圍中取不重複的隨機數
隨機取m
個數(在1到
n的範圍之內),(
m<=n)
,要求m
個數沒有重複。有沒有什麼好的演算法,時間複雜度和空間複雜度都很好?
方法一:用
stl中的
set集,紅黑樹來處理
取隨機數可以用c++
標準的rand
,至於m
個不重複,用
std::set
來解決,把取
到的隨機數插入到set
裡面,通過
set的
size()==m
來判斷是否已取夠
m個了。
#include #include int main()
//if
}//while
}
由於set
底層實現是紅黑樹,插入複雜度是對數級 。方
法二:
#include #include //用於rand()和srand()函式
#include //設定不同的隨機數
using namespace std;
int main ()
return 0;
}
1、
c++標準函式庫提供一隨機數生成器
rand
,返回0
~rand_max之間均勻分布的偽隨機整數。
rand_max
必須至少為
32767
。rand()
函式不接受引數,預設以
1為種子(即起始值)。隨機數生成器總是以相同的種子開始,所以形成的偽隨機數列也相同。失去了隨機意義。 2
、c++中另一函式
srand
(),可以指定不同的數(無符號整數變元)為種子。但是如果種子相同,偽隨機數列也相同。 3
、比較理想的是用變化的數,比如時間來作為隨機數生成器的種子。
在標頭檔案ctime
中時間庫包含
time
函式,它可以返回乙個表示時間、日期、月和年的數值使用如下呼叫可將該值設為
rand
的種子
srand(static_cast(time(static_cast(null))));
4. 但
srand()
並不是說使隨機數都不一樣
,它只是使取隨機數的種子隨著時間而改變。
方法三:
以下方法需要附加空間b
陣列,我們還是假設
100個資料。
(1)將範圍陣列
b[100](b[i]=100+i,
不妨設陣列下標從1開始
)的每個元素設定乙個標誌位
flag
,初始均為flag=0;
若某元素被選入到
a陣列中,則
flag=1;顯然,
以後再選到重複元素可以立刻判定是否已選
。但是仍然有乙個很嚴重的問題,
在小規模輸入下
,無疑它的表現是不錯的
。但現在舉乙個失敗的例子.
在1~65536之間,
選擇65500
個不重複的隨機數
,看看後面的隨機數,
比如第65500個數(
最後乙個
),它要在剩下的
36個數中選擇才會有
flag=0(
根本不知道這
36個數是什麼)。
改進:先在1~65536
之間隨機選取
36個數,刪除
.將剩下的
65500
個數依次賦值給
a[65500],
然後打亂順序即可。
當範圍陣列與目標陣列的大小非常接近時,
上述演算法非常有效
,建議採用。
(2)問題的最終解決.
仍以最開始的那個例子來說,
初始陣列
b[i]=100+i,a
陣列空。(
a是我們需要的存放生成的隨即數的陣列,我們需要從
b陣列中取數)
每次隨機生成陣列b
的乙個下標
subscript
,然後取出它所對應的資料
b[subscript],記下來
給a當前的儲存單位
a[j]
。然後將陣列b
的最後乙個數
b[length]
覆蓋b[
subscript
]的位置,同時將陣列a
指向下乙個數,
b陣列的長度減
1。儘管前若干次生成的下標subscript
隨機數有可能相同,但因為每一次都把最後乙個數填到取出的位置,因此,相同下標
subscript
對應的數卻絕不會相同,每一次取出的數都不會一樣,這樣,就保證了演算法的確定性、有效性、有窮性。
參考:
**
在給定範圍中取不重複的隨機數
在給定範圍中取不重複的隨機數 隨機取m個數 在1到n的範圍之內 m n 要求m個數沒有重複。有沒有什麼好的演算法,時間複雜度和空間複雜度都很好?方法一 用stl中的set集,紅黑樹來處理 取隨機數可以用c 標準的rand,至於m個不重複,用std set來解決,把取到的隨機數插入到set裡面,通過s...
Lua在給定範圍內,生成指定個數不重複隨機數組
生成隨機數組,暫時發現兩種方法 1 把生成的數放到乙個表裡面,每次隨機時判斷這個表裡是否有,若有再隨機一次 問了朋友,很多人都想到這個方法 2 先生成乙個連續的數字表t,每次隨機乙個數n,把t n 儲存,並移除t n 首先,說一下我的真實需求是給定一定範圍,然後生成指定個數的不重複隨機數組。這個給定...
不重複隨機數
1 不重複隨機數1 生產 lowerbound,upperbound 的隨機數,核心 int upperbound lowerbound 1 rnd lowerbound 示例 如下 sub rndnumnorepeat1 dimdic dim i set dic createobject scri...