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

来源:互联网 发布:3dmax unity3d 编辑:程序博客网 时间:2024/06/07 22:57

一.    实验要求

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

1)防伪码的组成

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

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

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

防伪码长度

防伪码个数

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

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

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

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

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

 

二.    设计思路

1.  开发时,在解决方案中,鼠标右键选择项目,然后点选“属性”,在“调试”项目中的“命令行参数”里面,可以预先输入需在命令行接收的参数,这样开发的时候就可以直接读入了

2.     防伪码生成思路 例如,有以下定义:

String strTableChar="0123456789ABCDEFGHJKLMNPQRSTUVWXYZ";

生成一个从0到strTableChar.Length的数字a,然后使用strTableChar[a]就可以随机返回一个字母,重复n次(n等于防伪码的长度),这样就可以组合到一串随机字符串,也就是防伪码了。

3.用于存储多个防伪码的集合,实验中关键的地方就是判断每次生成的防伪码是否已存在集合中。选HashSet<T>比List<T>更适合。HashSet集合中的对象是唯一的。HashSet的工作原理:每次存储对象的时候, 调用对象的hashCode()方法, 计算一个哈希值. 在集合中查找是否包含哈希值相同的元素.如果没有哈希值相同元素, 直接存入.如果有哈希值相同的元素, 逐个使用equals()方法比较。HashSet<T>的Contains方法的性能在大数据量时比List<T>好得多。HashSet<T>的Contains方法复杂度是O(1),List<T>的Contains方法复杂度是O(n)。

 

预先输入需在命令行接收的参数,接受命令行代码:

int length =Convert.ToInt32(args[0]);  //获取防伪码长度

       int icount = Convert.ToInt32(args[1]);  //获取要生成防伪码的个数

 

多次循环生成随机防伪码并且判断能否加入HashSet核心代码:

while (countNumber < icount)   //当前生成的防伪码少于要求生成个数时

 {

     while (i <length)          //用于循环生成每个防伪码的每位记录,多次使用

      {

           i2 = ramdom.Next(0, strTableChar.Length);    //多次随机生成每个防伪码的每个字符并存入字符串

          stringBuilder.Append(strTableChar[i2]);

            i++;

        }

       i = 0;

   StringS1 = stringBuilder.ToString(); //类型转化,要特别注意StringStringBulider区别

  if(liststring.Contains(S1));//如果生成的防伪码已在哈希集里,重新生成新的防伪码

   {stringBuilder.Length = 0; continue; }

 liststring.Add(S1);      //如果刚生成的防伪码不在哈希集里,就加进去哈希集

  stringBuilder.Length = 0;  //清空暂存防伪码的字符串

   countNumber++;

  }

 

三.    程序运行效果图

a)exe 10 10000


b) exe 20 1000000


x) exe 50 1000000


四.    实验总结

这是第一个C#作业。C#是一门面向对象的语言,许多地方与JAVA相似。但是由于大二对JAVA的学习不够认真,导致这个实验都耗费一定的时间。而且在实验中,有几个细节地方要总结一下:

   (1).String和stringBuilder的区别:String对象是不可变的。而StringBulider可以构建可变字符串,并且不创建新的对象。所以在判断随机生成的防伪码要添加到HashSet中,add方法必须是一个对象,所以要对StringBulider进行类型转换,才能添加新对象到泛型集合中。

   (2).HashSet<T>和List<T>性能比较:一开始使用List<T>的Contains方法,发现第一组数据还是能显示时间,第二组数据等了十多分钟还是没有结果。后来经过查询资料对两者的实现原理了解之后,发现采用散列函数的HashSet<T>速度非常好。而采用逐一遍历的List<T>对于大的数据就显得效率过低了。

     除了完成实验之外,我还有跟其他同学讨论,互相借鉴。有些同学对首次产生的防伪码进行全排列从而减少搜索比较次数,有些同学对判断条件进一步的优化。一次的实验我们不仅仅是为了解题,更重要的是要相互学习,相互共同进步。

     另外,通过这次实验,我意识到自己以前的JAVA学习的不佳导致学习效率偏低,这次简单的实验耗费了我6个小时的时间。其中很多时间是花在一些基础的知识的回顾如Ramdon函数,控制台输入输出,哈希表,还有相关知识的查阅。不过还是收获了很多。今天,我会更加努力学习,学好编程!

 

0 0
原创粉丝点击