控制台应用程序——随机数

作者:可乐fan  发布时间:2014-04-19 15:44:50

控制台应用程序——随机数

11软件工程1班        何桥         201130690105

一、实验要求

   这是一个实际的项目衍生出来的核心算法之一。防伪码是我们现在经常在商品上看到的防伪手段之一,现在需要编写一个防伪码生成器,按照输入参数生成防伪码,并且把生成的时间及指定的防伪码输出。

1)防伪码的组成

   防伪码由以下字符组成:0123456789ABCDEFGHJKLMNPQRSTUVWXYZ

  (数字1和字母I相近、数字0和字母O相近,所以去掉字母I和字母O。全部字母大写) 

2)在命令行中输入2个参数,分别是:

   防伪码长度

   防伪码个数

   例如:在命令行中调用程序为:学号.exe 10 10000

   指的是防伪码长度为10,生成10000个防伪码。

3)防伪码的生成及注意事项

   防伪码的长度由命令行参数决定

   所生成的防伪码不能重复(按照以上例子,生成了10000个防伪码,这10000个防伪码就肯定不能重复)。

< !--[if !supportLists]-->二、< !--[endif]-->采用的函数及思路

1.、开发时,对于输入数据的处理,根据格式输入“exe 防伪码长度 防伪码个数”读入防伪码的个数,由于C#不支持在一行里面读入两个数字,所以写了函数来实现这一功能。注意,不用对这些参数进行校验,默认输入的都是正确的参数,注意程序运行时的异常处理。

核心代码:

 public static void InputChar(ref int icount, ref int ilen)

        {

            try

            {

                Console.WriteLine("输入:长度 个数")

                string[] arg = Console.ReadLine().Split(' ')//根据空格拆分读入字符串

                icount = Convert.ToInt32(arg[0]) //输入的防伪码长度

                if (arg.Length > 1)//如果查分到两个字符串,即同时输入了两个参数

                {

                    ilen = Convert.ToInt32(arg[1]) //输入的防伪码个数

                }

                else//继续读下一个参数 {

                    ilen = Convert.ToInt32(Console.ReadLine())

                }

            }

            catch (Exception ex)//如果输入有误,抛出异常

            {

                throw new Exception(ex.Message)

            }

        }

2、然后根据防伪码的长度(icount)和个数(ilen)产生防伪码。生成一个从0到randomChar.Length的数字a,然后使用randomChar[a]就可以随机返回一个字母,重复icount次(icount等于防伪码的长度),这样就可以组合到一串随机字符串,也就是防伪码了。并将产生的防伪码加入到哈希集(hashSet)中。将防伪码*哈希集中,如果没有加入成功,即哈希集中没有重复的防伪码则总个数加1。循环地生成规定长度的防伪码直到总个数达到规定的要求。

核心代码:

public static void Randoms(int icount, int ilen)//生成防伪码

        {

            try

            {              

                HashSet hashSet = new HashSet()//哈希表

                Random List = new Random(DateTime.Now.Millisecond)//生成随机数

                StringBuilder str = new StringBuilder()

                for (int i = 0 i < ilen )

                {

                    str.Remove(0, str.Length)//当没有达到规定长度的时候继续生成防伪码                    for (int j = 0 j < icount j++)

                    {

                        str.Append(randomChar[List.Next(randomChar.Length)])//根据长度产生防伪码                    }

                    if (hashSet.Add(str.ToString()))//如果没有重复总数加1

                        i++

                }

            }

            catch (Exception ex)

            {

                throw new Exception(ex.Message)

            }

        }

程序运行效果图

1.第一组测试数据(10 10000),如下图所示:

 

2.第二组测试数据(20 1000000),如下图所示:

 

3.第三组测试数据(50 1000000),如下图所示:

 

三、总结

System.Random是最简单最常用的随机数发生器,如果用系统当前时间做种子,基本上可以做到“伪”随机。但是用System.Random得到的随机数的安全*是不高的,用户完全可以用一些方法根据已经生成的随机数序列预测出下一个随机数的值。

运用哈希表中的Contains方法直接比较两个防伪码的哈希码,而不是用ContainsValue直接比较两个防伪码是否相同,这样,由原先的On)时间复杂度降为O1),就可以发现防伪码是否重复。总体来说,这次的实验让我对哈希表和哈希集的运用有所加深,也深刻体会到了其便捷。