shuffle()方法——斗地主

本文详细介绍了Java中Collections.shuffle()方法的工作原理,该方法用于对列表进行随机置换。通过线性时间复杂度的算法实现,如果列表不支持高效随机访问,会先将其复制到数组再进行改组。同时,文章提到了使用指定随机源进行置换的情况,确保了置换的公平性。
摘要由CSDN通过智能技术生成
来源 API 1.6

public static void shuffle(List<?> list)

使用默认随机源对指定列表进行置换。所有置换发生的可能性都是大致相等的。

前面描述中使用了不确定的词“大致”,因为随机源只是大致上独立选择位的无偏源。如果它是一个随机选择位的最佳源,那么算法将完全一致的选择置换。

此实现向后遍历列表,从最后一个元素一直到第二个元素,将随机选择的元素重复交换到“当前位置”。元素是从列表的一部分随机选择的,该部分列表从第一个元素一直到当前位置(包括)。

此方法以线性时间运行。如果指定列表没有实现 RandomAccess 接口并且是一个大型列表,则此实现在改组列表前将指定列表转储到数组中,并将改组后的数组转储回列表中。这避免了二次行为,该行为是原地改组一个“有序访问”列表引起的。

 

参数:

list - 要改组的列表。

抛出:

UnsupportedOperationException - 如果指定列表或其列表迭代器不支持 set 操作。

---------------------------------------------------------------------------------------------------------

public static void shuffle(List<?> list,
                           Random rnd)

使用指定的随机源对指定列表进行置换。所有置换发生的可能性都是相等的,假定随机源是公平的。

此实现向后遍历列表,从最后一个元素一直到第二个元素,将随机选择的元素重复交换到“当前位置”。元素是从列表的一部分随机选择的,该部分列表从第一个元素一直到当前位置(包括)。

此方法以线性时间运行。如果指定列表没有实现 RandomAccess 接口并且是一个大型列表,则此实现在改组列表前将指定列表转储到一个数组中,并将改组后的数组转储回列表中。这避免了二次行为,该行为是原地改组一个“有序访问”列表引起的。

 

参数:

list - 要改组的列表。

rnd - 用来改组列表的随机源。

抛出:

UnsupportedOperationException - 如果指定列表或其列表迭代器不支持 set 操作。

public class doudizhu1 {
		public static void main(String[] args) {
			String[] arr = {"黑桃", "红心", "梅花", "方片"};
			String[] arr1 = { "A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K" };
			int m = 0;
			ArrayList<Integer> indexs = new ArrayList<>();//所有牌的角标
			ArrayList<String> cards = new ArrayList<>();//所有的牌,也就是规则,规则的排列顺序规则不变
			for (int i = 0; i < arr1.length; i++) {
				String string1 = arr1[i];

				for (int j = 0; j < arr.length; j++) {
					String string2 = arr[j];
					cards.add(string2 + string1);//将牌的规则定义好

					indexs.add(m);//将角标添加到 角标的集合当中
					m++;

				}
			}

			cards.add("大王");//添加未添加的牌
			cards.add("小王");
			indexs.add(52);//添加未添加的角标
			indexs.add(53);
			//洗的角标
			Collections.shuffle(indexs);//注意打乱的是角标

			ArrayList<Integer> list1 = new ArrayList<>();
			ArrayList<Integer> list2 = new ArrayList<>();
			ArrayList<Integer> list3 = new ArrayList<>();
			ArrayList<Integer> list4 = new ArrayList<>();

			for (int i = 0; i < indexs.size() - 3; i++) {//给每个玩家分发角标

				if (i % 3 == 0) {
					list1.add(indexs.get(i));

				} else if (i % 3 == 1) {
					list2.add(indexs.get(i));

				} else if (i % 3 == 2) {
					list3.add(indexs.get(i));

				}

			}
			//将底牌的角标添加进去
			list4.add(indexs.get(arr.length-1));
			list4.add(indexs.get(arr.length-2));
			list4.add(indexs.get(arr.length-3));
			
			
			
			//给所有玩家的拿到的角标进行排序
			Collections.sort(list1);
			Collections.sort(list2);
			Collections.sort(list3);
			Collections.sort(list4);
			//创建出每个玩家牌的集合
			ArrayList<String> qing = new ArrayList<>();
			ArrayList<String> zhi = new ArrayList<>();
			ArrayList<String> ru = new ArrayList<>();
			ArrayList<String> dipai = new ArrayList<>();
			//通过排好的角标顺序去拿牌;
			findCard(list1, qing, cards);
			findCard(list2, zhi, cards);
			findCard(list3, ru, cards);
			findCard(list4, dipai, cards);
			
			//看牌
			System.out.println(qing);
			System.out.println(zhi);
			System.out.println(ru);
			System.out.println(dipai);

		}
		//通过排好序的角标找牌
		/**
		 * 
		 * @param indexs  每位玩家排好角标顺序的集合
		 * @param player  每位玩家实际牌的集合
		 * @param sort    规则集合(需要通过排好序的角标查实际牌,添加到玩家实际牌的集合当中)
		 */
		public static void findCard(ArrayList<Integer> sortIndex,ArrayList<String> player,ArrayList<String> sort){
			for (int i = 0; i < sortIndex.size(); i++) {
				player.add(sort.get(sortIndex.get(i)));
			}
		}
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值