非重复随机数生成算法
生成非重复随机数的两种编程思路:
1、每次都在相同的范围内获取随机数,并将新生成的随机数与已生成的随机数逐一相比较,如果与已生成的随机数相同则重新获取随机数,若不同,则存储该随机数,继续获取下一个;
2、每次获取随机数时,都将之前生成的随机数排除在外,以保证生成的随机数不重复。
基于思路1,C++程序实现如下:
1 /******************************************************************** 2 * 3 * 文 件 名:Random.cpp 4 * 5 * 文件描述:生成不重复的随机数 6 * 7 * 创 建 人:crazyhf 2012年05月17日 8 * 9 * 版 本:1.0 10 * 11 * 修改记录: 12 * 13 ********************************************************************/ 14 15 # include <iostream> 16 # include <ctime> 17 # include <vector> 18 19 using std::cin ; 20 using std::cout ; 21 using std::endl ; 22 using std::vector ; 23 24 /*================================================================================= 25 * 26 * 函 数 名:CreateRandom 27 * 28 * 功能描述:在指定范围内生成n个不重复的随机整型数 29 * 30 * 参 数: 31 * vector < int > &randata :存放生成的的随机数 32 * int num :随机数的个数,也指定随机数的范围(0至num-1) 33 * 34 * 返 回 值:无返回值 35 * 36 * 抛出异常: 37 * 38 * 创 建 人:crazyhf 2012年05月17日 39 * 40 ==================================================================================*/ 41 42 void CreateRandom( vector < int > &randata , int num ) 43 { 44 int biggest = num ; 45 srand( ( unsigned ) time( 0 ) ); 46 47 while( num ) 48 { 49 int data = rand( ) % biggest ; 50 int size = randata.size( ); 51 int i = 0 ; 52 53 for( ; i < size && data != randata[i] ; i++ ) ; 54 55 if( i >= size ) 56 { 57 randata.push_back( data ); 58 num-- ; 59 } 60 } 61 } 62 63 int main( int argc , char **argv ) 64 { 65 int num ; 66 cout << "输入随机数个数:" ; 67 68 if( cin >> num ) 69 { 70 vector < int > randvec ; 71 72 CreateRandom( randvec , num ); 73 74 for( int i = 0 ; i < randvec.size( ) ; i++ ) 75 { 76 cout << randvec[i] << endl ; 77 } 78 } 79 80 return 0 ; 81 }
分析程序可知:每生成一个随机数都要耗费O(n)的时间复杂度来判断随机数是否重复,而生成的随机数有n个,故算法的时间复杂度为O(n^2);
此外该算法使用了vector来存放生成的随机数,故可知空间复杂度为O(n)。
基于上述算法,倘若采用HashMap来存放生成的随机数,则耗费的空间复杂度相同,但由于HashMap查找的时间复杂度为O(1),
故算法的时间复杂度可以优化为O(n)。
对于思路2,则可以借助数组来实现,具体C++实现代码如下:
1 /******************************************************************** 2 * 3 * 文 件 名:Random.cpp 4 * 5 * 文件描述:生成不重复的随机数 6 * 7 * 创 建 人:crazyhf 2012年05月17日 8 * 9 * 版 本:1.0 10 * 11 * 修改记录: 12 * 13 ********************************************************************/ 14 15 # include <iostream> 16 # include <ctime> 17 18 using std::cin ; 19 using std::cout ; 20 using std::endl ; 21 22 /*================================================================================= 23 * 24 * 函 数 名:RandomAry 25 * 26 * 功能描述:在指定范围内生成n个不重复的随机整型数 27 * 28 * 参 数: 29 * int num :随机数的个数,也指定随机数的范围(0至num-1) 30 * 31 * 返 回 值:成功则返回指向随机数存放空间的指针,失败则返回0 32 * 33 * 抛出异常: 34 * 35 * 创 建 人:crazyhf 2012年05月17日 36 * 37 ==================================================================================*/ 38 39 int *RandomAry( int num ) 40 { 41 if( !num ) return 0 ; 42 43 int *randomary = new int[ num ] ; 44 memset( randomary , -1 , num * sizeof( int ) ); 45 46 srand( ( unsigned ) time( 0 ) ); 47 48 while( num ) 49 { 50 int data = rand( ) % num-- ; 51 int temp = randomary[ num ] ; 52 53 if( randomary[ data ] == -1 ) 54 randomary[ num ] = data ; 55 else 56 randomary[ num ] = randomary[ data ] ; 57 58 if( temp == -1 ) 59 randomary[ data ] = num ; 60 else 61 randomary[ data ] = temp ; 62 } 63 64 return randomary ; 65 } 66 67 int main( int argc , char **argv ) 68 { 69 int num ; 70 cout << "输入随机数个数:" ; 71 72 if( cin >> num ) 73 { 74 int *ary = RandomAry( num ); 75 76 for( int i = 0 ; i < num ; i++ ) 77 { 78 cout << ary[i] << endl ; 79 } 80 delete []ary ; 81 } 82 83 return 0 ; 84 }