一种生成不重复数的算法

简介:
在编程中经常遇到一些类似的问题,比如做一个双色球选号软件,其中6个双色球是从1到33之间选出6个数来,这6个数是不能重复的,这个问题就是我们今天要说的生成不重复数算法。
算法描述如下:从M个数中选出N个数来(0<N<=M),要求N个数之间不能有重复。
这 个问题我以前用J2SE实现过,使用了ArrayList,每次随机在指定范围内选定一个数,然后查看结果集合中是否存在该数,如果存在继续下一轮循环, 如果不存在,就将该数保存到结果集合中去。使用这种算法虽然也能实现要求,缺点是判断结果集合中是否存在该数时,需要通过一个循环来判断,这会增加算法运 行的时间,虽然时间复杂度为n,但多次重复,还是一笔不小的开销。
下面要介绍的算法是,每次随机取出一个数,之后将该数放置到集合的末尾去,这样下次取随机数的时候,只从1到目标集合个数-1个中随机抽取,如此循环,这样就避免了判断在结果集合中判断是否存在相冲突的数的过程。
算法代码如下:
using  System;
using  System.Collections.Generic;
using  System.Text;
using  System.Diagnostics;
using  System.Management;

namespace  ConsoleApplication
{
    
class  Program
    {
        
static   void  Main( string [] args)
        {
            
int [] range  =   new   int [ 33 ];
            
for  ( int  i  =   0 ; i  <   33 ; i ++ ) // 初始化范围集合,从1到33
            {
                range[i] 
=  i  +   1 ;
            }
            
int [] result  =  CreateNumbers(range,  6 );
            
for ( int  i = 0 ;i < result.Length;i ++ )
            {
                Console.WriteLine(
" result[{0}]={1} " , i, result[i]);
            }
            Console.ReadKey();
        }
  
        
// 取出不重复的6个数
     static   int [] CreateNumbers( int [] range,  int  count)
        {
            
int [] result  =   new   int [count];
            Random random
= new  Random();
            
int  index  =   0 ;
            
int  temp  =   0 ;
            
for  ( int  i  =   0 ; i  <  count; i ++ )
            {
                index
= random.Next()  %  (range.Length - i);
                result[i] 
=  range[index];
                
// 将当前已使用过的数移至集合末尾,并且将末尾原来没有使用的数放到当前位置
                temp  =  range[range.Length  -   1 - i];
                range[range.Length 
-   1 - i]  =  range[index];
                range[index]
= temp;
            }
            
return  result;
        }
       
    }
}
结果如下:
补充一下,另外一种不使用数组而使用可变集合的办法,这种算法的做法是使用了之后马上从源集合中清除掉(数组是
没有办法这么做的),因而也是可以做到生成不重复的随机数的。具体代码如下:
// 取出不重复的6个数
         static  List < int >  CreateNumbers(List < int >  range,  int  count)
        {
            List
< int >  result  =   new  List < int > (count);
            Random random 
=   new  Random();
            
int  index = 0 ;
            
for  ( int  i  =   0 ; i  <  count; i ++ )
            {
                index
= random.Next() % range.Count;
                result.Add(range[index]);
                range.RemoveAt(index);
            }
            
return  result;
        }
至于用法,也很简单:
List < int >  range  =   new  List < int > ( 33 );
            
for  ( int  i  =   0 ; i  <   33 ; i ++ ) // 初始化范围集合,从1到33
            {
                range.Add(i 
+   1 );
            }
            List
< int >  result  =  CreateNumbers(range,  6 );
            
for  ( int  i  =   0 ; i  <  result.Count; i ++ )
            {
                Console.WriteLine(
" result[{0}]={1} " , i, result[i]);
            }

经万次测试,使用数组方法性能比使用List<int>范型集合高1/4。













本文转自周金桥51CTO博客,原文链接: http://blog.51cto.com/zhoufoxcn/163942,如需转载请自行联系原作者



相关文章
|
算法 Java
无重复字符的最长子串(算法Java)
无重复字符的最长子串(算法Java)
195 0
无重复字符的最长子串(算法Java)
|
前端开发 算法 JavaScript
LeetCode最大重复子字符串使用JavaScript解题|前端学算法
LeetCode最大重复子字符串使用JavaScript解题|前端学算法
146 0
LeetCode最大重复子字符串使用JavaScript解题|前端学算法
|
算法 前端开发 JavaScript
LeetCode无重复字符的最长子串使用JavaScript解题|前端学算法
前几天做LeetCode算法题,我还说要打十个,今天就被LeetCode狠狠打脸了 算了,难度大的做不出来,咱还做不出来简单的嘛,今天咱们就捡软柿子捏,来找找自信,昨天找了一下自信,我怕自信不够大,今天再找找
100 0
LeetCode无重复字符的最长子串使用JavaScript解题|前端学算法
|
算法
【Day34】LeetCode算法 -- 3. 无重复字符的最长子串
学习LeetCode算法 -- 3. 无重复字符的最长子串。
142 0
【Day34】LeetCode算法 -- 3. 无重复字符的最长子串
|
算法 索引
【Day15】算法刷题(解题思路+详细注释)[面试题 17.09. 第 k 个数 ][424. 替换后的最长重复字符 ][438. 找到字符串中所有字母异位词 ]
了解[面试题 17.09. 第 k 个数 ][424. 替换后的最长重复字符 ][438. 找到字符串中所有字母异位词 ]。
183 0
【Day15】算法刷题(解题思路+详细注释)[面试题 17.09. 第 k 个数 ][424. 替换后的最长重复字符 ][438. 找到字符串中所有字母异位词 ]
|
存储 算法
面试高频算法题---无重复字符的最长子串
给定一个字符串s,请你找出其中不含有重复字符的最长子串长度
面试高频算法题---无重复字符的最长子串
|
算法
【牛客刷题-算法】NC25 删除有序链表中重复的元素-I
【牛客刷题-算法】NC25 删除有序链表中重复的元素-I
94 0
【牛客刷题-算法】NC25 删除有序链表中重复的元素-I
|
算法 Go
算法练习第十题——寻找重复数(不修改数组)
给定一个包含 n + 1 个整数的数组 nums ,其数字都在 [1, n] 范围内(包括 1 和 n),可知至少存在一个重复的整数。
|
算法 C++
算法题每日一练---第67天:无重复字符的最长子串
给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。
134 0
算法题每日一练---第67天:无重复字符的最长子串
下一篇
DataWorks