随机数的不重复选择就是从n个数中随机选取m(m<n)个数。在本文中,我们用Java来实现。因此我们先介绍Java的相关知识。
在Java中,Java.util.Set接口和Java.util.List接口一样,都是继承自Java.util.Collection接口。但是两者有不同的特点:
List接口:一种
能包含重复元素的有序集合,具体实现该接口的类有:Vector、Stack、ArrayList、LinkedList等等.
Set接口:一种
不包含重复元素的集合,常见的实现该接口的类有:HashSet、LinkedHashSet、TreeSet。
为什么要想决解这个问题呢?因为在我仿真过程中,经常要用到随机数。比如随机的选取几个信道,随机的选取一定范围内的几个值。当然如果只是随机的选取一个值,直接用随机函数就可以了。但是当要选取多个值的时候,就可能出现重复的值(这不是我们所期望的)!
下面分别通过实现上述两个接口的类来实现随机数的不重复选择。
1.用实现List接口的向量来实现:
package tengwei.com; import java.util.*; public class UseVector { public static void main(String[] args) { // TODO Auto-generated method stub Vector<Integer> vec=selectSeven();//调用函数 Enumeration<Integer> enu=vec.elements();//得到向量中所有元素的枚举 while(enu.hasMoreElements())//遍历向量中的所有元素 System.out.println(enu.nextElement()+"\t"); Object obj[]=vec.toArray();//把向量vec转化为Oject数组 Arrays.sort(obj);//升序排序 System.out.println("升序排列后:"); for(int i=0;i<obj.length;i++) System.out.println(obj[i]+"\t"); } /**从1-36中随机选择7个不重复的数 */ public static Vector<Integer> selectSeven() { Random rd= new Random();//创建随机数对象 Vector<Integer> allNum = new Vector<Integer>();//存放1-36 Vector<Integer> sevenNum = new Vector<Integer>();//存放选择的7个数 for(int i=0;i<36;i++) allNum.add(new Integer(i+1));//向向量allNum中添加36个数 int x; for(int i=0;i<7;i++) { x=rd.nextInt(36-i);//得到0-(36-i)中随机数,不包含36-i sevenNum.add(allNum.get(x)); allNum.remove(x); } return sevenNum; } }本算法的基本思想就是先用Vector保存你的样本空间(36个数),然后产生一个随机数,以随机数为下标来取出样本空间的数,并且将该数从样本空间删除。 该算法的缺点是原始样本空间不能有重复的数,当样本空间很大的时候,会占用很多内存空间。当然还有几种算法也可以选择,具体请查看下一篇文章。
2.用实现Set接口的HashSet、TreeSet类来实现
首先分别介绍HashSet、TreeSet类:
HashSet类:该类实现了Set接口,由哈希表支持。它不保证集合的迭代顺序。该类不含参数的构造方法构造了一个空的哈希集,默认初始容量是16,加载因子是0.75。
TreeSet类:该类实现了Set接口的子接口SortedSet。它保证迭代器按照元素递增顺序遍历。插入该类的所有元素必须是可相互比较的,因为它必须保证递增顺序。
package tengwei.com; import java.util.*; public class UseHashSetTreeSet { public static void main(String[] args) { // TODO Auto-generated method stub Set<Integer> hashset = hashSelect(7);//调用函数,返回哈希集 System.out.println("HashSet中所有元素(未排列)"); System.out.println("\t"+hashset); SortedSet<Integer> treeset = treeSelect(7);//调用函数,返回数集 System.out.println("TreeSet中所有元素(升序)"); System.out.println("\t"+treeset); } public static Set<Integer> hashSelect(int k) { Random rd = new Random(); Set<Integer> hs= new HashSet<Integer>(); while(hs.size()<k) { int x=1+rd.nextInt(36);//随机1-36之间的数,包括两边 hs.add(new Integer(x)); } return hs; } public static SortedSet<Integer> treeSelect(int k) { Random rd = new Random(); SortedSet<Integer> ts= new TreeSet<Integer>(); while(ts.size()<k) { int x=1+rd.nextInt(36); ts.add(new Integer(x));//当重复时不会添加 } return ts; } }上面的算法比较简单,比较巧妙的用到了Set接口的特性。