当前位置: 首页 > 面试题库 >

随机/随机比较器

支阳波
2023-03-14
问题内容

有没有什么方法可以模拟Collections.shuffle的行为,而比较器不容易受到排序算法实现的影响,从而确保结果安全?

我的意思是不违反可比合同等。


问题答案:

不打破合同就不可能实现真正的“改组比较器”。Comparator合同的一个基本方面是,结果是可 重现的,
因此Comparator必须确定特定实例的顺序。

当然,您可以使用混洗操作预先初始化该固定顺序,并创建一个比较器来精确地建立此顺序。例如

List<ElementType> ordering=new ArrayList<>(list);
Collections.shuffle(ordering);

list.sort(Comparator.comparingInt(ordering::indexOf));

虽然没有意义。显然,此比较器 不得 用于包含不在ordering列表中的元素的集合。

或者,您可以使用没有排序顺序的值的稳定属性作为排序标准,例如哈希码。这可以通过稳定但可随机化的转换来增强,例如

public static Comparator<String> randomOrder() {
    ThreadLocalRandom r = ThreadLocalRandom.current();
    int x = r.nextInt(), y = r.nextInt();
    boolean b = r.nextBoolean();
    return Comparator.comparingInt((String s)->s.hashCode()^x)
     .thenComparingInt(s->s.length()^y)
     .thenComparing(b? Comparator.naturalOrder(): Comparator.reverseOrder());
}



List<String> list=Arrays.asList("hello", "now", "shuffle", "this", "!");
list.sort(randomOrder());
System.out.println(list);
list.sort(randomOrder());
System.out.println(list);

关键是每个Comparator实例代表一个随机选择但固定的顺序,我们创建一个新Comparator实例以请求不同的顺序。因此,没有Comparator违反合同。

请注意,这Comparator看起来有点复杂,因为它必须考虑可能的哈希冲突。然后它将诉诸于该length属性(也是随机的),并且对于String具有相同哈希码和长度的s,它将简单地退回到自然顺序或颠倒顺序,这不太可能引起注意,因为它仅影响这些罕见对的关系。

如果你创造价值这样的比较没有冲突(如Integer实例)或覆盖它定义了平等的价值的所有属性(比如他们,xy,的Point),比较会显得简单得多。



 类似资料:
  • 问题内容: 有没有什么方法可以模拟Collections.shuffle的行为,而比较器不容易受到排序算法实现的影响,从而确保结果安全? 我的意思是不违反可比合同等。 问题答案: 不打破合同就不可能实现真正的“改组比较器”。合同的一个基本方面是,结果是可 重现的, 因此必须确定特定实例的顺序。 当然,您可以使用混洗操作预先初始化该固定顺序,并创建一个比较器来精确地建立此顺序。例如 虽然没有意义。显

  • 配置 UserAgent 列表 @app.beans: [ 'UserAgentManager' => [ 'list' => [ // 这里可以放想要用的 UserAgent 列表 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36

  • 每次产生一个随机数。 用法 Your browser does not support the video tag. 案例:掷骰子 功能:设置随机数范围1-6,每按一下按钮,产生一个随机数 工作原理 当输入由no变为yes时,一个随机数将会被传送到输出。你可以通过配置改变随机数的范围 例如:一个随机变色的灯

  • 问题内容: 当他每次运行程序时都不断获得相同的数字时,我试图向Java解释随机数生成器。我为同一件事创建了自己的简单版本,每次运行该程序时,我也得到了与他得到的确切数字相同的数字。 我究竟做错了什么? 100个数字中的最后五个数字是: 问题答案: 您已经为随机数生成器提供了恒定的值。它是确定性的,因此每次运行都会生成相同的值。 我不确定您为什么选择使用作为种子,但是种子值与生成的值范围无关(这是由

  • 一个简单的新手问题,奇怪的是我一直没能找到解决方法。

  • 给定一个随机数生成器random(7),它可以以相等的概率生成数字1,2,3,4,5,6,7(即每个数字出现的概率为1/7)。现在我们要设计一个随机数(5),它能以相等的概率(1/5)生成1,2,3,4,5。 有一种方法:每次我们随机运行(7),只有当它生成1-5时才返回。如果是6或7,再运行一次,直到它是1-5。 我有点困惑。第一个问题是: 如何用数学方法证明每个数字发生的概率是1/5?例如,假