随机列表是我们常用的数据结构,我们一般会使用随机函数srand(),rand()取随机数来生成一个随机列表。
一个随机列表通常都有一定的范围,比如我们常常会听的mp3歌曲播放列表,里面有4首歌,那么随机播放时,每次的随机索引值都应该是0〜3。
但问题是我们希望随机列表不要在一个循环内多次的重复同一个index,并且每一个index都能被索引到。
请看下面一个例子:
void createRadomListSimple(int *pBuf, int length){
int i = 0;
for(i = 0; i < length; i ++){
pBuf[i] = rand() % length;
}
}
这个例子通过一个循环初始化了一个列表,并且将值通过“%length”将随机数限定在范围内,但是结果里常会有重复或者随机不到的现象,下面的在我本机上的打印结果:print list ...
1 1 2 2
print list ...
0 0 2 3
print list ...
1 0 1 0
这样的结果不是我们最理想的。
下面介绍一个生成不重复随机列表的方法,是通过随机放置循环的索引值来生成的随机列表,在上图的代码中,我们知道循环中使用的‘i’是永远不会重复的,通过rand将每一个循环中的‘i’随机放置到pBuf的某一个位置,我们就能得到一个不重复的随机列表了。
我们要解决一另个问题,避免pBuf被随机到的位置相同,利用在创建的过程中剩余的数据个数,我们能够查找到剩余数据的位置,再放置“循环索引值”就可以了,请参考下面的代码实现。
void createRadomList(int *pBuf, int length){
int index;
int j;
int remainNum;
int indexPosition; // index position of remaining empty data
unsigned int seed;
printf("create Radom list ....\n");
/*invalidate all index*/
for(index = 0; index < length; index ++){
pBuf[index] = -1;
}
/* seed */
seed = rand();
srand(seed+&length);
for(index = 0; index < length; index ++){
/* remain num of invalid data */
remainNum = length - index;
/* position for new generated index */
indexPosition = rand() % remainNum + 1;
/* searching physical position in pBuf */
for(j = 0; j < length; j ++){
if(pBuf[j] == -1){
indexPosition --;
}
if(indexPosition == 0){
break;
}
}
pBuf[j] = index;
}
}
下面是我本机的输出:
create Radom list ....
print list ...
0 3 2 1
create Radom list ....
print list ...
2 0 3 1
create Radom list ....
print list ...
2 0 1 3
create Radom list ....
print list ...
0 1 2 3
create Radom list ....
print list ...
2 3 0 1
create Radom list ....
print list ...
0 2 3 1
完美的随机列表就这么简单,再也不会重复了