在Java中,如何使一数组随机无序排列,即顺序打乱?

如何让数组元素无序排列?
刚开始我也有些蒙,只想到了用Random产生一个随机整数rd,再让数组元素向前移动rd个位置。但这种方法却不是真的无序排列,明显能看出和原数组的排列的关系,也就没有达到目的。
明显需要转变思路,可以从日常生活中的挑苹果得到经验。怎么随机从篮子里挑一个苹果,然后再放回去,再次挑一个苹果,而苹果外形都差不多,要保证此次挑出的苹果不是上一次挑过的苹果,这要怎么做到?我们可以在挑过的苹果上打一个标签,下次再挑一个苹果时,有意识地不去挑带有标签的苹果就是了。就这样重复多次,就能随机的挑出每个苹果。

1.先定义一个数组,再用Arrays工具类生成与此数组相同的副本

		int nums[]={12,14,13,15,18,19,20};									//原数组
		System.out.println("原数组是:"+Arrays.toString(nums));
		int[] copiedNums = Arrays.copyOf(nums,nums.length) ; 	//副本数组

2.再定义一个与数组所有元素均不同的标签数字,这个数字是算一个关键点。

		int countsDifferent=0; 	// 标签数字与数组元素不同的次数
		int different=0;		// 标签数字
		Random rd= new Random();	
		outCycle:				//外层循环标签
		/**产生标签数字并验证
		***/
		while(true){
			different=rd.nextInt();		// 	产生一个标签数字	
			for(int num : copiedNums){
			/**如标签数字与数组中任一元素相同,
			* 则退出内层循环,继续产生新的标签数字,进行
			* 下一次外层循环,即再次进行些内层循环中
			**/
				if(different == num ){
					break;		
					/**如标签数字与数组中任一元素不同,
					* 标签不同次数变量则加1,当countsDifferent等于
					* 数组长度时,则表明标签数字与数组所有元素都不同。
					* 此时退出外层循环,即整个二重循环体结束。标签数字
					* 达的值达到了设计目的。
					**/	
				}else{
					countsDifferent++;
					if(countsDifferent>=copiedNums.length){
						break outCycle;
					}
				} 
			}
		}

3.将副本数组的随机位置的一个不为different元素赋值给原数组的一元素,并将副本中的这一元素赋值为different标签数字。按此规律遍历数组。

		int index =0;			//副本数组的随机索引
		for(int i=0 ;i< nums.length; i++)
		{
			while(true)
			{
				/***生成副本数组的随机索引
				* 这时需要注意,我们需要0至nums.length-1范围
				* 的索引值。而Random的nextInt(int bound)方法,产生的是
				* [0,bound)范围的随机数,并不包括bound值,即此方法生成的
				* 是0至(bound-1)范围的数字。
				* 因边界因素,方法里的参数是num.length而不是num.lengh-1 。
				***/
				index = rd.nextInt(nums.length);	
				if(copiedNums[index] != different)
				{
					nums[i]=copiedNums[index]; //随机位置的副本元素赋值给原数组
					/***
					*将获取过的副本元素赋值为标签数字,以保证下一次获取的随机位置的副本元素不会 
					* 取到此元素。
					**/
					copiedNums[index]= different;		
					/***
					*原数组每在副本数组中新得一个非different值的随机位置的元素,则退出内层
					*循环,进行下一次外层循环,对下一索引的原数组元素赋值。
					**/
					break;	
				}
			}
		}
		System.out.println("无序后的数组:"+Arrays.toString(nums));
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值