在指定的范围内,生成不重复的随机数序列(排除法,筛选法)

b4c2的头像 b4c2 31 2014-12-31 22:57 0

 基本信息

× 1   

浏览数: 4737

分享时间: 4 年 前

1
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
 * 在指定的范围内,生成不重复的随机数序列
 */
public class UnrepeatRandomNumber {
	private int min;
	private int max;

	public UnrepeatRandomNumber() {
		this.min = 0;
		this.max = 10;
	}

	public UnrepeatRandomNumber(int min, int max) {
		this();
		if (max >= min) {
			this.min = min;
			this.max = max;
		} else {
			System.out.println("max比min小,按缺省值生成UnrepeatRandomNumber对象!");
		}
	}

	/**
	 * 第一种方法:排除法。随机生成数字,如果是新生成的数字,则放到结果列表种 否则是已经生成过的,则不加入结果列表,继续随机生成。
	 * 
	 * @param length
	 *            结果列表的长度
	 * @return
	 */
	public Integer[] getRandomMethodA(int length) {
		if (length <= 0) {
			return new Integer[0];
		} else if (length > (this.max - this.min)) {
			System.out.println("结果列表长度不能达到:" + length + ", 结果长度只能是:"
					+ (this.max - this.min));
			length = this.max - this.min;
		}
		Random rd = new Random();// 用于生成随机结果
		List resultList = new ArrayList();
		while (resultList.size() < length) {
			// 将[min, max]区间等价于min + [0, max - min + 1)
			Integer randnum = new Integer(this.min
					+ rd.nextInt(this.max - this.min + 1));
			if (!resultList.contains(randnum)) {
				resultList.add(randnum);
			}
		}
		// 使用toArray方法将List转换成对象数组返回
		return (Integer[]) resultList.toArray(new Integer[0]);
	}

	/**
	 * 第二种方法:筛选法。将所有可能被生成的数字放到一个候选列表中。 然后生成随机数,作为下标,将候选列表中相应下标的数字放到放到结果列表中,
	 * 同时,把它在候选列表中删除。
	 * 
	 * @param length
	 *            结果列表的长度
	 * @return
	 */
	public Integer[] getRandomMethodB(int length) {
		if (length <= 0) {
			return new Integer[0];
		} else if (length > (this.max - this.min)) {
			System.out.println("结果列表长度不能达到:" + length + ", 结果长度只能是:"
					+ (this.max - this.min));
			length = this.max - this.min;
		}
		// 初始化候选列表,列表长度为 max -min + 1
		int candidateLength = this.max - this.min + 1;
		List candidateList = new ArrayList();
		for (int i = this.min; i <= this.max; i++) {
			candidateList.add(new Integer(i));
		}

		Random rd = new Random();// 用于生成随机下标
		List resultList = new ArrayList();
		while (resultList.size() < length) {
			// 生成下标,在[0,candidateLength)范围内
			int index = rd.nextInt(candidateLength);
			// 将候选队列中下标为index的数字对象放入结果队列中
			resultList.add(candidateList.get(index));
			// 将下标为index的数字对象从候选队列中删除
			candidateList.remove(index);
			// 候选队列长度减去1
			candidateLength--;
		}
		// 使用toArray方法将List转换成对象数组返回
		return (Integer[]) resultList.toArray(new Integer[0]);
	}

	public static void outputArray(Integer[] array) {
		if (array != null) {
			for (int i = 0; i < array.length; i++) {
				System.out.print(array[i] + "  ");
			}
		}
		System.out.println();
	}

	public static void main(String[] args) {

		UnrepeatRandomNumber test = new UnrepeatRandomNumber(5, 15);
		outputArray(test.getRandomMethodA(8));
		outputArray(test.getRandomMethodB(8));
		// 相比之下,第一种方法利用Random对象生成的随机数的次数比较多,可能生成了20次数字,才能找到10个不一样的数字。
		// 第二种方法利用Random对象生成的随机数的次数比较少,需要多少个,就生成多少个,保证了每次生成的数字都不重复。
		// 也就是说第一种方法在时间花费上更多。但是第二种方法需要初始化一个候选队列,需要更多的空间花费。
	}
}


12 [下一页]

  • wzg356的头像 wzg356 2015-01-03 18:21 代码数:0
    先收集后消化
  • cixexey的头像 cixexey 2018-11-18 14:37 代码数:0

    Thank you for the update, very nice site..Umzugsfirma

  • jhoneila的头像 jhoneila 2019-01-16 15:32 代码数:0

    That is really nice to hear. thank you for the update and good luck.frame tents

  • jhoneila的头像 jhoneila 2019-01-19 14:45 代码数:0

    I wanted to thank you for this great read!! I definitely enjoying every little bit of it I have you bookmarked to check out new stuff you post.ukrayna üniversiteleri

  • cixexey的头像 cixexey 2018-10-04 18:34 代码数:0

    thanks for this usefull article, waiting for this article like this again.คอกีฬา

  • cixexey的头像 cixexey 2018-10-06 16:56 代码数:0

    I recently came across your blog and have been reading along. I thought I would leave my first comment. I don't know what to say except that I have enjoyed reading. Nice blog. I will keep visiting this blog very often. e zigarette liquid

  • jhoneila的头像 jhoneila 2019-01-24 14:39 代码数:0

    This is such a great resource that you are providing and you give it away for free.cong bong bong su kien

  • jhoneila的头像 jhoneila 2019-01-26 14:59 代码数:0

    You completed a few fine points there. I did a search on the subject and found nearly all persons will go along with with your blog. remove popcorn ceiling

  • jhoneila的头像 jhoneila 2019-01-27 14:59 代码数:0

    I recently found many useful information in your website especially this blog page. Among the lots of comments on your articles. Thanks for sharing. Sem Seo

  • jhoneila的头像 jhoneila 2019-01-29 15:45 代码数:0

    This is really a nice and informative, containing all information and also has a great impact on the new technology. Thanks for sharing it, youtube promotion

您的评论: