昨天无聊,就模仿仙剑5外传中的卡牌游戏做了一个小游戏,结果在开发这个小游戏的时候,碰到了产生多个不同随机数的问题。我们知道,仙剑中的卡牌游戏是随机产生16张图片,并且这16张图片是两个一组的,因为只有选中了相同的图片,这一组图片才能消除。所以这个问题,可以简化为:随机产生n个随机数,且保证每个数字都有唯一的一个数字和它对应。如1、3、4、6、7、6、1、3、4、7这样一组数字。那么这个问题怎么解决呢?首先我们先思考怎样产生n个不同的随机数,如果直接使用Random类,我们不能保证这n个随机数互不相同。我的思路是用递归的方法,即对于每一个随机产生的数,进行一次检查,如果已经存在这个数,那么立即用一个新的随机数进行替换,你可能会问,你怎么保证,这个新生成的随机数就不会和已知的随机数重复的,这时候,递归就派上了用场。下面我们来看代码:

 public  int[] GetRandom(int length, int min, int max)
{
Random r=new Random();
int[] temp = new int[length];
for (int i = 0; i < length; i++)
{
temp[i] = r.Next(min, max);
Program.CheckRandom(temp, temp[i], min, max);
}
return temp;
} public int CheckRandom(int[] items,int value,int min,int max)
{
int n = 0;
Random r=new Random();
while (n <= items.Length - 1)
{
if (items[n] == value)
{
value = r.Next(min, max);
CheckRandom(items, value, min, max);
}
n++;
}
return value;
}

其中GetRandom用于获取n个不同的随机数,CheckRandom用于检查随机数,另外,给出下面的一篇文章供大家参考:

http://blog.csdn.net/lynnlin1122/article/details/2318906

那么到这里,我们只是解决了第一个问题,即产生n个不同的随机数。在实际的问题中,我们还需要以某种特殊的方式,得到它的另一半。由于这里的数据个数是偶数,我们很容易的想到先取出一半随机数填充前面的n/2个位置,再随机将前面的这一半的随机数随机地填充到后面的n/2个位置。所以,其算法描述为:

1、使用GetRandom获取前面的n/2个随机数,进行填充。

2、保存前面得到的数组

3、使用GetRnadom获取从n/2+1到n之间的随机数

4、将第二部保存的数组按照第三步得到的随机数索引,从n/2+1个位置起填充数组

下面是程序允许的一些截图:

偶尔会出现一张照片出现超过两次的问题,目前还没发现是为什么,如果大家知道,希望可以告诉我。嘻嘻

喜欢仙剑的童鞋可以点这里:http://download.csdn.net/detail/qinyuanpei/6244993

产生n不同随机数的算法的更多相关文章

  1. Redis源代码分析(23)--- CRC循环冗余算法RAND随机数的算法

    他今天就开始学习Redis源代码的一些工具来实现,在任何一种语言工具.算法实现的原理应该是相同的,一些比較经典的算法.比方说我今天看的Crc循环冗余校验算法和rand随机数产生算法. CRC算法全称循 ...

  2. Java随机数生产算法

    java提供了Math.random()函数,返回一个double类型的随机数,也有util包里的Random类,可以生成double,int,float,long,bytes等随机数. 但有些业务需 ...

  3. C语言之实现随机数产生算法

    随机数,也就是在不同的时刻产生不同的数值.在UNIX操作系统和window的操作系统上,我们知道有一个函数rand,它就是用来产生随机数的函数API接口,那么它的原理如何实现? 如果约定a1=f(se ...

  4. JavaScript 随机数相关算法

    // Math.ceil() 返回大于等于数字参数的最小整数(取整函数),对数字进行上舍入 // Math.floor() 返回小于等于数字参数的最大整数,对数字进行下舍入 // Math.round ...

  5. 洗牌算法Fisher-Yates以及C语言随机数的产生

    前些天在蘑菇街的面试中碰到一道洗牌的算法题,拿出来和大家分享一下! 原题是:54张有序的牌,如何无序的发给3个人? 这个题是运用经典的洗牌算法完成.首先介绍一种经典的洗牌算法--Fisher-Yate ...

  6. 基于“均态分布”随机数算法的一次性口令OneTimePassword(原创)

    /* 所谓均态分布随机数算法是指:每个数(整数或实数)无序地分布在数轴上,值只出现一次永不重复.体现了香农的一次一密理论. * 均体现在每个数的值是平均概率,即都有出现:态体现在每个数在数轴上的位置是 ...

  7. C语言基础(11)-随机数发生器

    一. rand() rand是一个C语言库函数,功能是生成一个随机数.rand需要一个不同的种子,才能生成不同的随机数. 二. srand(int seed) rand需要一个不同的种子,才能生成不同 ...

  8. 【原创】开源Math.NET基础数学类库使用(13)C#实现其他随机数生成器

                   本博客所有文章分类的总目录:[总目录]本博客博文总目录-实时更新  开源Math.NET基础数学类库使用总目录:[目录]开源Math.NET基础数学类库使用总目录 前言 ...

  9. 随机数是骗人的,.Net、Java、C为我作证(转)

    几乎所有编程语言中都提供了"生成一个随机数"的方法,也就是调用这个方法会生成一个数,我们事先也不知道它生成什么数.比如在.Net中编写下面的代码: Random rand = ne ...

随机推荐

  1. Android Studio安装教程

    Google在2013 I/O大会上发布Android Studio之后,广大Android开发者欢欣鼓舞,不过很快就有人出现问题,Android Studio无法安装,或者安装后无法启动,这篇文章就 ...

  2. GPSR协议移植

    修改的文件有packet.h.cmu-trace.cc.priqueue.cc.ns-packet.tcl.Makefile 1.在 $HOME/ns-allinone-2.29/ns-2.29下新建 ...

  3. perl 传递对象到模块

    perl 中的对象 就是引用 通过new方法传递数据结构给各个模块 [root@wx03 test]# cat x1.pm package x1; use Data::Dumper; sub new ...

  4. vim添加删除多行注释

    CTRL+V进入可视化模式 移动光标上移或者下移,选中多行的开头 选择完毕后,按大写的的I键,此时下方会提示进入“insert”模式,输入你要插入的注释符 最后按ESC键,你就会发现多行代码已经被注释 ...

  5. [置顶] c#验证码识别、图片二值化、分割、分类、识别

    c# 验证码的识别主要分为预处理.分割.识别三个步骤 首先我从网站上下载验证码 处理结果如下: 1.图片预处理,即二值化图片 *就是将图像上的像素点的灰度值设置为0或255. 原理如下: 代码如下: ...

  6. WebBrowser与IE的关系,如何设置WebBrowser工作在IE9模式下?

    原文 WebBrowser与IE的关系,如何设置WebBrowser工作在IE9模式下? 一.问题的提出 偶然发现,Winform里的WebBrowser和IE实际安装的版本似乎并不同步,很有趣! 下 ...

  7. c:foreach如何嵌套循环,求指教,求优化

    java类: public class PopedomItem { private String id; private String pid; private String name; privat ...

  8. /bin/bash^M: 坏的解释器: 没有那个文件或目录

    在Linux下编译cocos2d-x运行脚本的时候出现”/bin/bash^M: 坏的解释器: 没有那个文件或目录“这样的错误如下图. 解决方法: 使用在终端输入sed -i 's/\r$//' ma ...

  9. 【视频】零基础学Android开发:蓝牙聊天室APP(四)

    零基础学Android开发:蓝牙聊天室APP第四讲 4.1 ListView控件的使用 4.2 BaseAdapter具体解释 4.3 ListView分布与滚动事件 4.4 ListView事件监听 ...

  10. zoj1028-Flip and Shift

    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=28 题意:有相互交叉的黑白两种颜色的小球,每一个小球每次可以跳两格:问你是否可以 ...