方法一:Knuth
时间复杂度O(n)
1 void genknuth(int m,int n){ 2 for(int i=0;i<n;i++){ 3 if(bigrand()%(n-i)<m){ 4 cout<<i<<endl; 5 m--; 6 } 7 } 8 }
方法二:每次插入O(log m)
时间复杂度O(m log m)
缺点:(1)set数据结构的空间开销比较大(128M内存大约在m=1,700,000时就不够用了,而该内存可存储32,000,000个int(4个字节)
(2)当m接近n时,基于集合的算法生成的很多随机数都要丢弃,因为之前已存在集合中
1 void gensets(int m,int n){ 2 set<int> s; 3 while(s.size()<m) 4 s.inset(bigrand()%n); 5 for(set<int>::iterator i=s.begin();i!=s.end();i++) 6 cout<<*i<<endl; 7 }
方法三:打乱数组的前m个元素
时间复杂度O(n+m log m),空间复杂度O(n)
1 void genshuf(int m, int n){ 2 int x[n]; 3 for(int i=0;i<n;i++) 4 x[i]=i; 5 for(int i=0;i<m;i++){ 6 j=randint(i,n-1); 7 swap(x[i],x[j]); 8 } 9 sort(x,x+m); 10 for(int i=0;i<m;i++) 11 cout<<x[i]<<endl; 12 }