【问题标题】:Get a non-prime number and its factors below a given maximum得到一个非素数及其因子低于给定最大值
【发布时间】:2015-10-01 12:16:53
【问题描述】:

我需要随机选择一个低于给定最大值的非质数,并返回其所有因数。

我已经将所有非素数及其因数存储在 Map<Integer, Integer[]> 中,该Map<Integer, Integer[]> 在启动时计算一次。

以下是实现的想法:

public Pair<Integer, Integer[]> getNonPrimeAndFactors(int maximum)
{
    //Randomly select a non-prime less than maximum
    return new Pair<Integer, Integer[]>(nonPrime, factors.get(nonPrime));
}

我不确定要使用什么数据结构来随机选择 Map 中的密钥,同时仍然小于 maximum。选择一个小于最大值的随机数,然后向下迭代调用factors.hasKey(randomNumber--) 会有点废话。

我使用的是 Java 7 和 Guava,所以可以从 Google 的集合中挑选。

【问题讨论】:

    标签: java collections guava


    【解决方案1】:

    您可以通过将密钥集转换为SortedSet 并保持头部集低于最大值来获得小于最大值的随机密钥。

    当你有这样一个集合时,就可以将它转换为一个列表并通过索引获取一个随机元素:

    public Pair<Integer, Integer[]> getNonPrimeAndFactors(int maximum) {
        SortedSet<Integer> set = new TreeSet<>(factors.keySet()).headSet(maximum);
        List<Integer> keys = new ArrayList<>(set);
        Integer nonPrime = keys.get(ThreadLocalRandom.current().nextInt(keys.size()));
        return new Pair<Integer, Integer[]>(nonPrime, factors.get(nonPrime));
    }
    

    【讨论】:

    • 感谢您的持续努力,但这仍然行不通。集合中会有空隙。如果最大值为 4,随机数为 4,则列表中的第 4 个条目将为 9。这高于请求的最大值。
    • @Deejay 如果最大值为 4,则头戴设备将仅包含数字 1,因此随机数将始终为 0,因为随机密钥是从头戴设备中选择的。
    • 啊,抱歉 - 我不明白 headSet 究竟做了什么。
    • @Deejay 它返回集合的视图,其中包含(严格来说)小于最大值的所有元素。要包括最大值,您可以致电headSet(max, true)
    • 非常感谢。当我正在编写一个对垃圾收集敏感的游戏时,我最终得到了一个 List&lt;Optional&lt;Integer[]&gt;&gt; 并包含了具有 absent 值的素数,然后完全按照我所说的那样做,只是重复下去直到我得到一个非素数。它们是如此稀疏,这可能是最有效的方式。
    【解决方案2】:

    生成一个低于最大值的随机数,通过查看表格检查它是否为非质数。如果是从头开始的素数重启,即生成一个新的随机数。

    由于非素数比素数更频繁,这个过程不会花费很长时间。

    【讨论】:

    • 谢谢——关于素数的低频你说得对,我并没有真正考虑过它的实际意义。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-04
    相关资源
    最近更新 更多