在编程中经常遇到一些类似的问题,比如做一个双色球选号软件,其中6个双色球是从1到33之间选出6个数来,这6个数是不能重复的,这个问题就是我们今天要说的生成不重复数算法。
算法描述如下:从M个数中选出N个数来(0<N<=M),要求N个数之间不能有重复。
这个问题我以前用J2SE实现过,使用了ArrayList,每次随机在指定范围内选定一个数,然后查看结果集合中是否存在该数,如果存在继续下一轮循环,如果不存在,就将该数保存到结果集合中去。使用这种算法虽然也能实现要求,缺点是判断结果集合中是否存在该数时,需要通过一个循环来判断,这会增加算法运行的时间,虽然时间复杂度为n,但多次重复,还是一笔不小的开销。
下面要介绍的算法是,每次随机取出一个数,之后将该数放置到集合的末尾去,这样下次取随机数的时候,只从1到目标集合个数-1个中随机抽取,如此循环,这样就避免了判断在结果集合中判断是否存在相冲突的数的过程。
算法代码如下:
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Text;
usingSystem.Diagnostics;
usingSystem.Management;
namespaceConsoleApplication
{
classProgram
{
staticvoidMain(string[]args)
{
int[]range=newint[33];
for(inti=0;i<33;i++)//初始化范围集合,从1到33
{
range[i]=i+1;
}
int[]result=CreateNumbers(range,6);
for(inti=0;i<result.Length;i++)
{
Console.WriteLine("result[{0}]={1}",i,result[i]);
}
Console.ReadKey();
}
//取出不重复的6个数
staticint[]CreateNumbers(int[]range,intcount)
{
int[]result=newint[count];
Randomrandom=newRandom();
intindex=0;
inttemp=0;
for(inti=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;
}
returnresult;
}
}
}
结果如下:
补充一下,另外一种不使用数组而使用可变集合的办法,这种算法的做法是使用了之后马上从源集合中清除掉(数组是
没有办法这么做的),因而也是可以做到生成不重复的随机数的。具体代码如下:
//取出不重复的6个数
staticList<int>CreateNumbers(List<int>range,intcount)
{
List<int>result=newList<int>(count);
Randomrandom=newRandom();
intindex=0;
for(inti=0;i<count;i++)
{
index=random.Next()%range.Count;
result.Add(range[index]);
range.RemoveAt(index);
}
returnresult;
}
至于用法,也很简单:
List<int>range=newList<int>(33);
for(inti=0;i<33;i++)//初始化范围集合,从1到33
{
range.Add(i+1);
}
List<int>result=CreateNumbers(range,6);
for(inti=0;i<result.Count;i++)
{
Console.WriteLine("result[{0}]={1}",i,result[i]);
}
经万次测试,使用数组方法性能比使用List<int>范型集合高1/4。
分享到:
相关推荐
标题中的“生成永不重复数字的算法”是一种设计用于创建唯一标识符的技术,它在数据库管理和分布式系统中尤为重要。这样的算法通常需要确保在给定的数字范围内不会产生重复,并且能够高效地进行加密和解密操作。描述...
本文将深入探讨一种在Java中实现的高效算法,该算法能够生成指定范围内的不重复随机数数组,特别适用于随机组题等应用场景。 ### 核心知识点解析 #### 1. 算法原理 算法的核心思想是首先创建一个包含指定范围内...
Fisher-Yates洗牌算法是一种有效的生成不重复随机数的方法。它通过对数组进行随机交换来达到目的。 **示例代码**: ```java import java.util.*; public class Test { public static void main(String[] args) { ...
在Java编程中,生成验证码是一种常见的需求,通常用于身份验证或防止机器人自动操作。验证码的目的是确保用户是人类,而不是机器。在这个问题中,我们关注的是如何生成四位字符且无重复的验证码,以及如何进一步确保...
这种方法通过直接对原始数组进行打乱操作来生成不重复的随机数序列。 ```vb Private Sub Command1_Click() Randomize Timer Dim A(1 To 10) As Integer Dim B(1 To 8) As String Dim i As Integer, k As Integer...
在这个场景中,我们关注的是一个使用易语言编写的源码,该源码旨在生成6位不重复的数字组合。易语言是一种面向初学者和专业开发者的中文编程语言,它以其直观的语法和丰富的库函数,使得编程变得更加简单。 "组合6...
在Java编程中,生成十个不重复的随机数是一项常见的任务,尤其在进行数据模拟、测试或者游戏设计等场景。要实现这个功能,我们需要利用到Java的集合框架和Math类中的随机数生成方法。下面我们将详细讲解如何实现这个...
伪随机数生成器是基于数学公式或特定序列的算法,它们可以快速生成看起来随机的数,但实际上是可重复的,只要知道初始种子(seed)。TRNG则是基于物理现象,如电子噪声,生成真正的随机数,无法预测且不可重复。 在...
### 一种软件生成真随机数的算法研究 #### 摘要及背景 本文探讨了随机数的本质,即确保每一个比特位(bit)都具备随机性,并提出了一种基于软件实现的真随机数生成方法。在信息安全、加密解密、模拟仿真等领域中,...
并查集是一种数据结构,用于处理一些不相交集合的合并与查询。在迷宫生成中,可以将迷宫的每个单元格看作一个集合,通过并查集维护它们的连通性。初始时,所有单元格都是独立集合,然后随机选择两个未连接的单元格...
模重复平方算法是一种用于计算a的b次方对模数m取模的高效方法。在公钥密码系统如RSA中,这个操作是核心计算之一。传统的乘法方式会随着指数b的增长变得非常慢,而模重复平方算法通过每次将指数折半来显著提高效率。...
在易语言中,生成不重复随机数是一项常见的需求,特别是在游戏开发、数据分析或者算法设计等场景。本文将深入探讨如何在易语言中实现取不重复随机数的功能。 首先,我们需要了解易语言中的随机数生成函数。在易语言...
数独是一种广受欢迎的逻辑推理游戏,其基本规则是在9×9的大九宫格中填入数字1到9,使得每个小九宫格(3×3的子网格)、每行、每列都包含且仅包含一次这9个数字。唯一解数独指的是生成的数独谜题有且只有一个解决...
"易语言组合6位不重复数字"就是一个这样的实例,它涉及到算法设计、数组操作以及数学概念。易语言是一种中国本土开发的编程语言,其语法简洁,易于学习,特别适合初学者和非计算机专业人员。 首先,我们要理解什么...
遗传算法(Genetic Algorithm, GA)作为一种模仿自然选择和遗传机制的全局搜索算法,在处理大规模、非线性以及不连续的问题方面表现出了良好的性能。然而,对于某些特定问题,如旅行商问题(Traveling Salesman ...
算法是信息技术领域中至关重要的概念,它是一种有明确规则和步骤的方法,用于解决特定问题或完成特定任务。算法的性质包括输入、输出、确定性和有限性。算法必须能够接收零个或多个输入,由外部提供,然后至少产生一...
雪花算法(Snowflake)是Twitter开源的一种分布式ID生成算法,它能有效地生成全局唯一的64位ID,这在很多场景下可以替代传统的UUID。 雪花算法的核心思想是将ID分为多个部分,分别是时间戳、工作节点ID和序列号,...
数独游戏的生成算法是其核心,而挖洞思想是一种创新的数独生成方法,其基本原理是先生成一个完整的数独解决方案,然后通过特定的规则逐渐删除一些数字,使得解决方案变成一个数独谜题,同时保证该谜题有一个唯一的...
**遗传算法**是一种启发式搜索方法,灵感来源于生物进化过程。它通过模拟自然选择、遗传变异等机制来寻找问题的最优解。遗传算法具有较强的全局搜索能力,并且能够有效避免陷入局部最优解。这种算法在组合优化问题、...