首页 > 其他分享 >你会用shuffle打乱列表吗?

你会用shuffle打乱列表吗?

时间:2022-12-13 21:36:23浏览次数:33  
标签:shuffle 你会用 int 打乱 list 000% 00000 time size

    在网站上我们经常会看到关键字云(Word Cloud)和标签云(Tag Cloud),用于表明这个关键字或标签是经常被查阅的,而且还可以看到这些标签的动态运动,每次刷新都会有不一样的关键字或便签,让浏览者觉得这个网站的访问量非常大,短短的几分钟就有这么多的搜索量。这是怎么实现的呢?其实非常简单:先从数据库中读出标签,然后使用随机数打乱,每次都产生不同的顺序,嗯,确实能让浏览者感觉到我们的标签云顺序在变——浏览者多嘛!但是,对于乱序处理我们有哪些方法呢?

下面给出一个大家都会想到的方法:

public <T> void shuffle1(List<T> list) {
int size = list.size();
Random random = new Random();

for(int i = 0; i < size; i++) {
// 获取随机位置
int randomPos = random.nextInt(size);

// 当前元素与随机元素交换
T temp = list.get(i);
list.set(i, list.get(randomPos));
list.set(randomPos, temp);
}
}

很简单,实现方法也很多,但有更简单的实现方法:

public <T> void shuffle2(List<T> list) {
int size = list.size();
Random random = new Random();

for(int i = 0; i < size; i++) {
// 获取随机位置
int randomPos = random.nextInt(size);

// 当前元素与随机元素交换
Collections.swap(list, i, randomPos);
}
}

上面使用了Collections的swap方法,该方法会交换两个位置的元素值,不用我们自己写交换代码了,是不是更简单呢?

其实,我想说,还有更更简单的方法,如下:

public <T> void shuffle3(List<T> list) {
// 打乱顺序
Collections.shuffle(list);
}

这才是我们想要的结果,就这一句话即可打乱一个列表的顺序,不用我们费尽心思的遍历、替换元素了!

现在来测试一下,是不是都能成功实现打乱顺序呢?下面给出完整源代码:

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

/**
* 打乱列表中数据元素的三种实现方法
*/
public class ShuffleTest {

// 打乱列表实现方法1
public <T> void shuffle1(List<T> list) {
int size = list.size();
Random random = new Random();

for(int i = 0; i < size; i++) {
// 获取随机位置
int randomPos = random.nextInt(size);

// 当前元素与随机元素交换
T temp = list.get(i);
list.set(i, list.get(randomPos));
list.set(randomPos, temp);
}
}

// 打乱列表实现方法2
public <T> void shuffle2(List<T> list) {
int size = list.size();
Random random = new Random();

for(int i = 0; i < size; i++) {
// 获取随机位置
int randomPos = random.nextInt(size);

// 当前元素与随机元素交换
Collections.swap(list, i, randomPos);
}
}

// 打乱列表实现方法3
public <T> void shuffle3(List<T> list) {
// 打乱顺序
Collections.shuffle(list);
}

// 打印列表
public <T> void print(List<T> list) {
for(T t : list) {
System.out.print(t + " ");
}

System.out.println("\n");
}

/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub

ShuffleTest st = new ShuffleTest();
List<String> tagClouds = new ArrayList<String>(6);

// 一般从数据库中读取,这里仅以测试为目的
tagClouds.add("计算机");
tagClouds.add("Java");
tagClouds.add("编程");
tagClouds.add("C/C++");
tagClouds.add("操作系统");
tagClouds.add("数据库");
System.out.println("原顺序:");
st.print(tagClouds);

st.shuffle1(tagClouds);
System.out.println("打乱顺序一:");
st.print(tagClouds);

st.shuffle2(tagClouds);
System.out.println("打乱顺序二:");
st.print(tagClouds);

st.shuffle3(tagClouds);
System.out.println("打乱顺序三:");
st.print(tagClouds);
}

}

输出结果如下:

你会用shuffle打乱列表吗?_java

我们一般很少用到shuffle这个方法,那它可以用在什么地方呢?

(1)可以用在程序的“伪装”上
比如我们例子中的标签云,或者是游戏中的打怪、修行、群殴时宝物的分配策略。

(2)可以用在抽奖程序中
比如年会的抽奖程序,先使用shuffle把员工顺序打乱,每个员工的中奖几率就是相等的了,然后就可以抽取第一名、第二名。

(3)可以用在安全传输方面
比如发送端发送一组数据,先随机打乱顺序,然后加密发送,接收端解密,然后自行排序,即可实现即使是相同的数据源,也会产生不同密文的效果,加强了数据的安全性。


import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.springframework.util.StopWatch;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
* @author: tangcheng
* @description:
* @since: Created in 2018/08/07 11:01
*/
@Slf4j
public class CollectShuttleTest {

/**
* 从1000个中去掉100个,总耗时18ms
* 混淆后的数据,没有发现明显的问题
*/
@Test
public void shuffleTest() {
List<Integer> total = new ArrayList<>();
for (int i = 0; i < 1000; i++) {
total.add(i);
}
StopWatch stopWatch = new StopWatch("Collections.shuffle()");
int count = 100;
List<Integer> winnerList = new ArrayList<>(100);
for (int i = 0; i < count; i++) {
stopWatch.start("time_" + i);
Collections.shuffle(total);
int index = total.size() - 1;
Integer winner = total.remove(index);
winnerList.add(winner);
log.info("taskName:{},winner:{}", i, winner);
stopWatch.stop();
}
log.info("winnerList:{},stopWatch.prettyPrint():{}", winnerList, stopWatch.prettyPrint());
/**
* winnerList:[
* 163, 905, 954, 828, 387, 217, 272, 662, 753, 160,
* 636, 629, 132, 318, 655, 388, 501, 879, 625, 515,
* 339, 897, 497, 959, 819, 654, 71, 984, 356, 256,
* 539, 330, 888, 643, 928, 10, 213, 878, 935, 206,
* 53, 875, 437, 422, 997, 464, 276, 65, 451, 732,
* 432, 154, 385, 955, 161, 719, 352, 383, 37, 853,
* 675, 696, 646, 223, 742, 807, 76, 738, 415, 516,
* 890, 656, 610, 910, 80, 7, 561, 548, 947, 390,
* 949, 236, 382, 338, 112, 240, 162, 642, 754, 571,
* 8, 802, 532, 410, 372, 462, 880, 38, 744, 360
* ],
* stopWatch.prettyPrint():StopWatch 'Collections.shuffle()': running time (millis) = 18
* -----------------------------------------
* ms % Task name
* -----------------------------------------
* 00007 039% time_0
* 00000 000% time_1
* 00000 000% time_2
* 00001 006% time_3
* 00000 000% time_4
* 00000 000% time_5
* 00000 000% time_6
* 00000 000% time_7
* 00000 000% time_8
* 00000 000% time_9
* 00000 000% time_10
* 00000 000% time_11
* 00001 006% time_12
* 00000 000% time_13
* 00000 000% time_14
* 00000 000% time_15
* 00000 000% time_16
* 00000 000% time_17
* 00000 000% time_18
* 00000 000% time_19
* 00000 000% time_20
* 00000 000% time_21
* 00000 000% time_22
* 00000 000% time_23
* 00001 006% time_24
* 00000 000% time_25
* 00000 000% time_26
* 00000 000% time_27
* 00001 006% time_28
* 00000 000% time_29
* 00001 006% time_30
* 00000 000% time_31
* 00000 000% time_32
* 00000 000% time_33
* 00000 000% time_34
* 00000 000% time_35
* 00000 000% time_36
* 00000 000% time_37
* 00000 000% time_38
* 00000 000% time_39
* 00000 000% time_40
* 00001 006% time_41
* 00000 000% time_42
* 00000 000% time_43
* 00000 000% time_44
* 00000 000% time_45
* 00000 000% time_46
* 00000 000% time_47
* 00000 000% time_48
* 00000 000% time_49
* 00000 000% time_50
* 00001 006% time_51
* 00000 000% time_52
* 00000 000% time_53
* 00000 000% time_54
* 00000 000% time_55
* 00000 000% time_56
* 00000 000% time_57
* 00000 000% time_58
* 00000 000% time_59
* 00000 000% time_60
* 00000 000% time_61
* 00000 000% time_62
* 00001 006% time_63
* 00000 000% time_64
* 00000 000% time_65
* 00001 006% time_66
* 00000 000% time_67
* 00000 000% time_68
* 00000 000% time_69
* 00000 000% time_70
* 00000 000% time_71
* 00000 000% time_72
* 00000 000% time_73
* 00000 000% time_74
* 00000 000% time_75
* 00000 000% time_76
* 00001 006% time_77
* 00000 000% time_78
* 00000 000% time_79
* 00000 000% time_80
* 00000 000% time_81
* 00000 000% time_82
* 00000 000% time_83
* 00000 000% time_84
* 00000 000% time_85
* 00000 000% time_86
* 00000 000% time_87
* 00000 000% time_88
* 00000 000% time_89
* 00000 000% time_90
* 00000 000% time_91
* 00001 006% time_92
* 00000 000% time_93
* 00000 000% time_94
* 00000 000% time_95
* 00000 000% time_96
* 00000 000% time_97
* 00000 000% time_98
* 00000 000% time_99
*/
}


}

 



标签:shuffle,你会用,int,打乱,list,000%,00000,time,size
From: https://blog.51cto.com/u_15147537/5935155

相关文章

  • 开篇 | 揭秘 Flink 1.9 新架构,Blink Planner 你会用了吗?
    本文为ApacheFlink新版本重大功能特性解读之FlinkSQL系列文章的开篇,FlinkSQL系列文章由其核心贡献者们分享,涵盖基础知识、实践、调优、内部实现等各个方面,带你由浅......
  • Codeforces Global Round 10 H. ZS Shuffles Cards
    题目链接设f[i]表示还有i个数不在集合内的期望步数,尝试列一下转移式,会发现式子由转移到下一轮的期望步数和之后的DP值组成,考虑DP的转移过程,就会发现答案为转移到下一轮的......
  • MapReduce作业Map阶段和Reduce阶段重要过程详述(Partitioner、Combiner、Shuffle三个阶
    MapReduce作业Map阶段和Reduce阶段重要过程详述(Partitioner、Combiner、Shuffle)MapReduce作业Map阶段和Reduce阶段重要过程详述(Partitioner、Combiner、Shuffle三个阶段的解......
  • CF1392H ZS Shuffles Cards 题解
    linkDescription有\(n\)张数字牌以及\(m\)张鬼牌,有一个不可重集合\(S\),初始为空。不断执行以下操作:抽出一张牌,如果为数字牌,则加入\(S\)并移除。如果为鬼牌,如果......
  • 随机打乱数组--java实现
    参考链接听说过java.utils.Random随机数是伪随机,但是Math库还没学,所以下面代码中还是用的Randompublicstaticint[]shuffle(int[]arr){Randomr=newRandom(......
  • 384. 打乱数组(洗牌算法)
    给你一个整数数组 nums ,设计算法来打乱一个没有重复元素的数组。打乱后,数组的所有排列应该是 等可能 的。实现 Solution class:Solution(int[]nums) 使用整数数......
  • java——集合——Collections工具类——Collections集合工具类的方法——addAll&shuff
    Collection集合工具类的方法一java.utils.Collections是集合工具类,用来对集合进行操作。部分方法如下:publicstaticbooleanaddAll(Collectionc,T...elements):往集......
  • 让Excel中的图表自动转化为PPT,你会用VBA来实现这个动作吗
    我们都知道Excel的图表功能是十分强大的,那么你在制作PPT的时候,肯定会遇上把我们在表格中的数据直接拿到我们的PPT中间使用。当然你也许会说,我们其实在PPT中也可以使用这个功......
  • 打乱数组
    给你一个整数数组nums,设计算法来打乱一个没有重复元素的数组。打乱后,数组的所有排列应该是 等可能 的。实现Solutionclass:Solution(int[]nums)使用整数数组num......
  • CF1622D. Shuffle 题解 组合数学/枚举
    题目链接:​​https://codeforces.com/problemset/problem/1622/D​​题目大意:给定一个长度为\(n\)的01字符串\(s\),你可以对这个字符串进行最多一次操作,该次操作需要选择......