在编程中经常遇到一些类似的问题,比如做一个双色球选号软件,其中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。

转载于:https://www.cnblogs.com/zhoufoxcn/archive/2007/10/24/2515759.html

一种生成不重复数的算法相关推荐

  1. 【计算机图形学】 圆的两种生成算法(角度微分法、Bresenham算法)

    圆的两种生成算法(角度微分法.Bresenham算法) 文章目录 1.角度微分法的原理 2.角度微分法的实现(基于matlab) 3.Bresenham 算法的原理 4.Bresenham 算法的实现 ...

  2. idgenerator 会重复吗_终极版:分布式唯一ID的几种生成方案

    在业务开发中,大量场景需要唯一ID来进行标识:用户需要唯一身份标识.商品需要唯一标识.消息需要唯一标识.事件需要唯一标识等,都需要全局唯一ID,尤其是复杂的分布式业务场景中全局唯一ID更为重要. 那么 ...

  3. 【面试锦囊】14种模式搞定面试算法编程题(8-14)

    面试锦囊之知识整理系列 面试锦囊系列一直有收到大家的反馈,包括后台内推成功的消息.朋友的同事从创业小公司成功跳到huawei等等,非常高兴小破号的这些整理分享能够真正地帮助到大家,以后也会继续.为了更 ...

  4. Paxos算法是莱斯利·兰伯特(Leslie Lamport)1990年提出的一种基于消息传递的一致性算法。

    Paxos算法是莱斯利·兰伯特(Leslie Lamport)1990年提出的一种基于消息传递的一致性算法.Paxos算法解决的问题是一个分布式系统如何就某个值(决议)达成一致.在工程实践意义上来说, ...

  5. 详解4种经典的限流算法

    最近,我们的业务系统引入了Guava的RateLimiter限流组件,它是基于令牌桶算法实现的,而令牌桶是非常经典的限流算法.本文将跟大家一起学习几种经典的限流算法. 限流是什么? 维基百科的概念如下 ...

  6. 分布式唯一ID的几种生成方案

    分布式ID的特性 唯一性:确保生成的ID是全网唯一的. 有序递增性:确保生成的ID是对于某个用户或者业务是按一定的数字有序递增的. 高可用性:确保任何时候都能正确的生成ID. 带时间:ID里面包含时间 ...

  7. 掌握一种基本图形元素光栅化算法,利用OpenGL实现直线光栅化的DDA算法。

    一.任务描述 根据下面要求,在右侧修改代码,绘制出预期输出的图片.平台会对你编写的代码进行测试. 1.本关任务 掌握一种基本图形元素光栅化算法,利用OpenGL实现直线光栅化的DDA算法. 2.预期输 ...

  8. 四种不同单源最短路径算法性能比较

    四种不同单源最短路径算法性能比较   一.最短路径问题描述 单源最短路径描述:给定带权有向图G=(V,E),其中每条边的权是非负实数.另外,还给定V中的一个顶点,称之为源.现在要计算从源到其他各顶点的 ...

  9. 弥合鸿沟:一种生成内部威胁数据的实用方法(Bridging the Gap: A Pragmatic Approach to Generating Insider Threat Data )

    Bridging the Gap: A Pragmatic Approach to Generating Insider Threat Data 弥合鸿沟:一种生成内部威胁数据的实用方法 摘要:恶意内 ...

最新文章

  1. spring集成rabbitmq遇到的问题
  2. python爬虫机器_Python常用的机器学习库|python爬虫|python入门|python教程
  3. cad2016珊瑚_预测有马的硬珊瑚覆盖率
  4. WordPress网站弹窗插件PopupPress插件
  5. nginx配置官网yum源
  6. 线程同步(windows平台):信号量
  7. MFC在一个工程中启动其他工程的exe文件
  8. win10怎样更改系统字体_怎样用电脑光盘重装win10系统?电脑光盘重装系统步骤图文教程...
  9. 常用问题排查工具和分析神器,值得收藏
  10. SnagIt - 官方网站
  11. 微服务网关SpringCloud Gateway
  12. 34. 脱壳篇-FSG压缩壳、ImportREC修复IAT输入表的使用,令一种寻找OEP方式
  13. 免费得了一套做自媒体教程,免费分享给大家
  14. 中国音频放大器市场现状研究分析与发展前景分析报告
  15. Syzmlw 蜗居大结局f
  16. MapReduce实现矩阵乘法的一些总结
  17. 三级等保 MySQL8.0.24审计日志功能开启
  18. 企业用免费邮箱哪个好
  19. Context-Free Grammar及形状规则集
  20. 解锁iPhone密码锁?

热门文章

  1. Logstash在Linux上安装部署
  2. nginx伪静态之try_files和rewrite讲解
  3. 把office文档转换为html过程中的一些坑
  4. 数据加密之MD5加密
  5. Excel 单元格隐藏
  6. android开发年总结
  7. 关于WSE_CLIPSIBLINGS
  8. Android开发之多Fragment切换优化
  9. ArrayList的几种初始化方法
  10. 计算机硬件2部件指的是什么,计算机基础-2.计算机硬件基础.doc