【Java编程】随机数的不重复选择

      随机数的不重复选择就是从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接口的特性。

原文:http://blog.csdn.net/tengweitw/article/details/24395949

作者:nineheadedbird

时间: 2024-11-08 22:15:07

【Java编程】随机数的不重复选择的相关文章

【算法编程】随机数的不重复选择

       前一篇文章中,我们在Java中用实现两种不同接口的类,解决了不重复选择随机数的问题.现在我们在C++中,通过几种不同的算法来解决上述问题.在下面的四种算法实现中,用的随机函数都是C的库函数,这个函数产生的随机数的范围是限定的,[0, 32767].当然我们可以通过四则运算来改变取值范围.具体的算法实现如下: #include<iostream> #include<ctime> #include<algorithm> #include <set>

Java编程中随机数的生成方式总结_java

本章先讲解Java随机数的几种产生方式,然后通过示例对其进行演示. 广义上讲,Java中的随机数的有三种产生方式: (01). 通过System.currentTimeMillis()来获取一个当前时间毫秒数的long型数字. (02). 通过Math.random()返回一个0到1之间的double值. (03). 通过Random类来产生一个随机数,这个是专业的Random工具类,功能强大.第1种 利用System.currentTimeMillis()获取随机数通过System.curre

Java获取随机数的3种方法_java

主要介绍了Java获取随机数的3种方法,主要利用random()函数来实现 方法1 (数据类型)(最小值+Math.random()*(最大值-最小值+1))例: (int)(1+Math.random()*(10-1+1)) 从1到10的int型随数 方法2 获得随机数 for (int i=0;i<30;i++) {System.out.println((int)(1+Math.random()*10));} (int)(1+Math.random()*10) 通过java.Math包的ra

Java编程准则

编程|准则 Java编程准则内容摘录自:<Java 编程思想>第2版<附录C J a v a 编程准则>/(美) 埃克尔(Eckel,B)著:候捷译的,机械工业出版社,2002.9 版权归原作者和原出版社. 这份附录所提供的建议,可以帮助你进行低阶的程序设计,并帮助你写码. 当然,这些都只是一种方针而不是硬性规则.你应该视它们为一种灵感来源.记住,某些情况下你需要加以变通或甚至打破规则.设计 1. 优雅需要付出代价.从短期利益来看,对某个问题提出优雅的解决方法,似乎可能花你更多的时

Java 编程要点之并发(Concurrency)详解

本文详细介绍了 Java 并发(Concurrency)的基础用法和原理. 计算机用户想当然地认为他们的系统在一个时间可以做多件事.他们认为,他们可以工作在一个字处理器,而其他应用程序在下载文件,管理打印队列和音频流.即使是单一的应用程序通常也是被期望在一个时间来做多件事.例如,音频流应用程序必须同时读取数字音频,解压,管理播放,并更新显示.即使字处理器应该随时准备响应键盘和鼠标事件,不管多么繁忙,它总是能格式化文本或更新显示.可以做这样的事情的软件称为并发软件(concurrent softw

Java 编程要点之 I/O 流详解

本文详细介绍了 Java I/O 流的基础用法和原理. 字节流(Byte Streams) 字节流处理原始的二进制数据 I/O.输入输出的是8位字节,相关的类为 InputStream 和 OutputStream. 字节流的类有许多.为了演示字节流的工作,我们将重点放在文件 I/O字节流 FileInputStream 和 FileOutputStream 上.其他种类的字节流用法类似,主要区别在于它们构造的方式,大家可以举一反三. 用法 下面一例子 CopyBytes, 从 xanadu.t

Java编程性能优化技巧有哪些

1.尽量在合适的场合使用单例 使用单例可以减轻加载的负担,缩短加载的时间,提高加载的效率,但并不是所有地方都适用于单例,简单来说,单例主要适用于以下三个方面: 第一,控制资源的使用,通过线程同步来控制资源的并发访问: 第二,控制实例的产生,以达到节约资源的目的: 第三,控制数据共享,在不建立直接关联的条件下,让多个不相关的进程或线程之间实现通信. 2.尽量避免随意使用静态变量 要知道,当某个对象被定义为static变量所引用,那么GC通常是不会回收这个对象所占有的内存,如: 此时静态变量b的生命

Java编程中10个最佳的异常处理技巧_java

在实践中,异常处理不单单是知道语法这么简单.编写健壮的代码是更像是一门艺术,在本文中,将讨论Java异常处理最佳实践.这些Java最佳实践遵循标准的JDK库,和几个处理错误和异常的开源代码.这还是一个提供给java程序员编写健壮代码的便利手册.Java 编程中异常处理的最佳实践 这里是我收集的10个Java编程中进行异常处理的10最佳实践.在Java编程中对于检查异常有褒有贬,强制处理异常是一门语言的功能.在本文中,我们将尽量减少使用检查型异常,同时学会在Java编程中使用检查型VS非检查型异常

Java编程那些事儿3——你适合学习程序设计吗?

 Java编程那些事儿3--你适合学习程序设计吗?作者:陈跃峰出自:http://blog.111cn.net/mailbomb          程序设计是一个技术活,所以不是适合所有的人.现在很多人听说程序设计人员待遇如何如何的好,都一窝蜂的来学习程序,其实这个现象很不正常,因为程序不一定适合你.其实对于一个人来说,适合你的才是最好的.         就像现在很多小孩子都被家长逼着去学钢琴啊什么,有些小孩根本没有艺术细胞的,所以学习的效果就是差强人意了.         其实程序设计最需要