生成不重复的随机数

        题目

        生成不重复的随机数,例如在1~10中生成6个不重复的随机数。

方法一

        首先想到的思路是用数组存放1~10整数,在循环便利的时候可以通过一个值记录生成的随机数并将其改成-1进行判断,如果是-1就在循环一次,直到输出6个随机数。代码如下

public static void main(String[] args) {
			
			contrast(a, b);
			//用于存放随机生成的6个数
			int[] numbers = new int[6];
			//存放1~10的数组
			int[] total = new int[10];
			for (int i = 0; i < total.length; i++) {
				total[i] = i+1;
			}
			randomNumber(total, numbers);
			System.out.println(Arrays.toString(numbers));
		
		}
        //生成不重复随机数方法
		public static void randomNumber(int[] total,int[] numbers) {
			Random r = new Random();
            //记录生成随机数的个数
			int number = 0;
			int num = -1;
			do {
                //生成随机数在数组中的下标
				int index = r.nextInt(total.length);

				if (total[index]!= -1) {
					numbers[number] = total[index];
					number++;
					total[index]=num;
				}else {
					continue;
				}
				
				
			} while (number < 6);
		}

 缺点

        题目的数据需求量较少,但如果需求量变大,比如在1~500之间生成400个不重复的随机数,次方法的运行时间就会变长,且可能会出现便利很久都是-1的情况。

方法二

        改进方法有很多,我了解到的有一种觉得是比较好的,不会随着数组和需求量的变大而变得麻烦反而会越来越简单。

        还是一样先用一个数组存放1~10,再用定义一个数组存放生成的随机数,生成随机数的下标通过下标找到数组中的数;不同点在于每一次将随机数赋值之后,通过下标将该数移动到数组的最后一位,然后在下次循环遍历时生成的随机数范围减一,这样每一次循环后随机数都会移动到后面且生成的随机数的下标会越来越少且数字不会重复,需要生成几个随机数就循环几次。代码如下

public static void main(String[] args) {
			contrast(a, b);
			//用于存放随机生成的6个数
			int[] numbers = new int[6];
			//存放1~30的数组
			int[] total = new int[10];
			for (int i = 0; i < total.length; i++) {
				total[i] = i+1;
			}
			randomNumber(total, numbers);
			System.out.println(Arrays.toString(numbers));
		
		}

//生成不重复随机数算法
		public static void randomNumber(int[] total,int[] numbers) {
			Random r = new Random();
			//用于记录随机生成的数组下标
			int index = -1;   
			//只循环6次
			for (int i = 0; i < numbers.length; i++) {
				//将生成的下标赋值给index
				//total.length-i是为了将每次生成的随机数的范围减少,避免重复
				index = r.nextInt(total.length-i);
				//将生成的随机数储存到目标数组中
				numbers[i] = total[index];
				
				//将生成的随机数与数组中的数进行交换,避免重复
				int temp = total[index];
				//随着循环的进行,随机数和数组中倒数第一、倒数第二、倒数第三。。。。。。进行交换
				total[index] = total[total.length-1-i];
				total[total.length-1-i] = temp; 
				
				
			}
		}	

拓展

        这种方法可以适用于很多场景提高效率,不必再一次次的对比遍历,例如对比两个数组中相同的元素。

		public static void main(String[] args) {
			int[] a = {1,3,5,7,9};
			int[] b = {1,2,3,4,5};
			//比较a和b中相同元素的个数
            contrast(a, b);
		
		}

        public static void contrast(int[] a,int[] b) {
			int num = 0;
			for (int i = 0; i < a.length; i++) {
				for (int j = 0; j < b.length-num; j++) {
					if (a[i] == b[j]) {
                       // 把数组b中与a相同的元素挪到b数组的最后,之后对比时不用对比最后一个
					   //如果说第一个对比时相同的,则下一次对比只需对比4次
                        int temp = b[j];
						b[j] = b[b.length-1-num];
						b[b.length-1-num] = temp;
						num++;
					}
				}
			}
			System.out.println(num);
		}

        这个是我在学习过程中了解到的一个我觉得很好的方法,希望可以帮到有缘人。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值