作者: Jerry Cat
時間: 2006/05/16
鏈接: http://www.cppblog.com/jerysun0818/archive/2006/05/16/7232.html
問題的來由 - "隨機取m個數(在1到n的範圍之內),(m <= n),要求m個數沒有重複。有沒有
什麼好的算法,時間複雜度和空間複雜度都很好"
----------------------------------------------------------------
方案一:
取隨機數可以用C++標準的rand,至於M個不重複,你可以用std::set來解決,把取道的隨機數
插入到set裏面,set的size() == m就可以了, 具體可以這樣:
#include <set>
#include <stdlib.h>
int main()
{
std::set<int> s;
while(1)
{
int r = rand() % n;
s.insert(r);
if(s.size() == m)
{
break;
}
}
}
由於set底層實現是紅黑樹,插入複雜度是對數級的^_^
----------------------------------------------------------------
方案二:
#include <iostream>
#include <cstdlib> //用於rand()和srand()函數
#include <ctime> //設置不同的隨機數
using namespace std;
int main (){
srand( time( 0 ) ); //調用不重複的隨機數函數
unsigned i;
for ( int n = 0; n++ < 10; )
{
i = rand() ; //對i 賦系統的隨機數
cout << " The NO." << n << "is : " << i << endl;
}
return 0;
}
1. C++標準函數庫提供一隨機數生成器rand,返回0-RAND_MAX之間均勻分佈的僞隨機整數。 RAND_MAX
必須至少爲32767。rand()函數不接受參數,默認以1爲種子(即起始值)。
隨機數生成器總是以相同的種子開始,所以形成的僞隨機數列也相同。失去了隨機意義。
2. C++中另一函數srand(),可以指定不同的數(無符號整數變元)爲種子。但是如果種子相同,僞
隨機數列也相同。--一個辦法是讓用戶輸入種子,但是仍然不理想。
3. 比較理想的是用變化的數,比如時間來作爲隨機數生成器的種子。
在 頭文件ctime中時間庫包含time函數,它可以返回一個表示時間、日期、月和年的數值使用如
下調用可將該值設爲rand的種子
srand(static_cast<unsigned>(time(static_cast<time_t*>(NULL))));
4. 但, srand()並不是說使隨機數都不一樣,它只是使取隨機數的種子隨着時間而改變:)
So, 還是方案一好!