一种生成不重复数的算法
在编程中经常遇到一些类似的问题,比如做一个双色球选号软件,其中6个双色球是从1到33之间选出6个数来,这6个数是不能重复的,这个问题就是我们今天要说的生成不重复数算法。
算法描述如下:从M个数中选出N个数来(0<N<=M),要求N个数之间不能有重复。
这个问题我以前用J2SE实现过,使用了ArrayList,每次随机在指定范围内选定一个数,然后查看结果集合中是否存在该数,如果存在继续下一轮循环,如果不存在,就将该数保存到结果集合中去。使用这种算法虽然也能实现要求,缺点是判断结果集合中是否存在该数时,需要通过一个循环来判断,这会增加算法运行的时间,虽然时间复杂度为n,但多次重复,还是一笔不小的开销。
下面要介绍的算法是,每次随机取出一个数,之后将该数放置到集合的末尾去,这样下次取随机数的时候,只从1到目标集合个数-1个中随机抽取,如此循环,这样就避免了判断在结果集合中判断是否存在相冲突的数的过程。
算法代码如下:
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;
}
}
}
结果如下:
补充一下,另外一种不使用数组而使用可变集合的办法,这种算法的做法是使用了之后马上从源集合中清除掉(数组是
没有办法这么做的),因而也是可以做到生成不重复的随机数的。具体代码如下:
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;
}
至于用法,也很简单:
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
一种生成不重复数的算法相关推荐
- 【计算机图形学】 圆的两种生成算法(角度微分法、Bresenham算法)
圆的两种生成算法(角度微分法.Bresenham算法) 文章目录 1.角度微分法的原理 2.角度微分法的实现(基于matlab) 3.Bresenham 算法的原理 4.Bresenham 算法的实现 ...
- idgenerator 会重复吗_终极版:分布式唯一ID的几种生成方案
在业务开发中,大量场景需要唯一ID来进行标识:用户需要唯一身份标识.商品需要唯一标识.消息需要唯一标识.事件需要唯一标识等,都需要全局唯一ID,尤其是复杂的分布式业务场景中全局唯一ID更为重要. 那么 ...
- 【面试锦囊】14种模式搞定面试算法编程题(8-14)
面试锦囊之知识整理系列 面试锦囊系列一直有收到大家的反馈,包括后台内推成功的消息.朋友的同事从创业小公司成功跳到huawei等等,非常高兴小破号的这些整理分享能够真正地帮助到大家,以后也会继续.为了更 ...
- Paxos算法是莱斯利·兰伯特(Leslie Lamport)1990年提出的一种基于消息传递的一致性算法。
Paxos算法是莱斯利·兰伯特(Leslie Lamport)1990年提出的一种基于消息传递的一致性算法.Paxos算法解决的问题是一个分布式系统如何就某个值(决议)达成一致.在工程实践意义上来说, ...
- 详解4种经典的限流算法
最近,我们的业务系统引入了Guava的RateLimiter限流组件,它是基于令牌桶算法实现的,而令牌桶是非常经典的限流算法.本文将跟大家一起学习几种经典的限流算法. 限流是什么? 维基百科的概念如下 ...
- 分布式唯一ID的几种生成方案
分布式ID的特性 唯一性:确保生成的ID是全网唯一的. 有序递增性:确保生成的ID是对于某个用户或者业务是按一定的数字有序递增的. 高可用性:确保任何时候都能正确的生成ID. 带时间:ID里面包含时间 ...
- 掌握一种基本图形元素光栅化算法,利用OpenGL实现直线光栅化的DDA算法。
一.任务描述 根据下面要求,在右侧修改代码,绘制出预期输出的图片.平台会对你编写的代码进行测试. 1.本关任务 掌握一种基本图形元素光栅化算法,利用OpenGL实现直线光栅化的DDA算法. 2.预期输 ...
- 四种不同单源最短路径算法性能比较
四种不同单源最短路径算法性能比较 一.最短路径问题描述 单源最短路径描述:给定带权有向图G=(V,E),其中每条边的权是非负实数.另外,还给定V中的一个顶点,称之为源.现在要计算从源到其他各顶点的 ...
- 弥合鸿沟:一种生成内部威胁数据的实用方法(Bridging the Gap: A Pragmatic Approach to Generating Insider Threat Data )
Bridging the Gap: A Pragmatic Approach to Generating Insider Threat Data 弥合鸿沟:一种生成内部威胁数据的实用方法 摘要:恶意内 ...
最新文章
- spring集成rabbitmq遇到的问题
- python爬虫机器_Python常用的机器学习库|python爬虫|python入门|python教程
- cad2016珊瑚_预测有马的硬珊瑚覆盖率
- WordPress网站弹窗插件PopupPress插件
- nginx配置官网yum源
- 线程同步(windows平台):信号量
- MFC在一个工程中启动其他工程的exe文件
- win10怎样更改系统字体_怎样用电脑光盘重装win10系统?电脑光盘重装系统步骤图文教程...
- 常用问题排查工具和分析神器,值得收藏
- SnagIt - 官方网站
- 微服务网关SpringCloud Gateway
- 34. 脱壳篇-FSG压缩壳、ImportREC修复IAT输入表的使用,令一种寻找OEP方式
- 免费得了一套做自媒体教程,免费分享给大家
- 中国音频放大器市场现状研究分析与发展前景分析报告
- Syzmlw 蜗居大结局f
- MapReduce实现矩阵乘法的一些总结
- 三级等保 MySQL8.0.24审计日志功能开启
- 企业用免费邮箱哪个好
- Context-Free Grammar及形状规则集
- 解锁iPhone密码锁?