建立一个不重复的随机列表

随机列表是我们常用的数据结构,我们一般会使用随机函数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

完美的随机列表就这么简单,再也不会重复了



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值