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

使用Eratosthenes筛子查找素数(原文:有更好的方法来准备此数组吗?)

淳于泓
2023-03-14
问题内容

注意:
下面的版本2使用Eratosthenes筛。有几个答案可以帮助我解决最初提出的问题。我选择了Eratosthenes的Sieve方法,实现了该方法,并适当地更改了问题标题和标签。感谢所有提供帮助的人!

介绍

我写了这个花哨的小方法,它生成一个整数数组,该数组包含小于指定上限的质数。它工作得很好,但我有一个担心。

方法

private static int [] generatePrimes(int max) {
    int [] temp = new int [max];
    temp [0] = 2;
    int index = 1;
    int prime = 1;
    boolean isPrime = false;
    while((prime += 2) <= max) {
        isPrime = true;
        for(int i = 0; i < index; i++) {
            if(prime % temp [i] == 0) {
                isPrime = false;
                break;
            }
        }
        if(isPrime) {
            temp [index++] = prime;
        }
    }
    int [] primes = new int [index];
    while(--index >= 0) {
        primes [index] = temp [index];
    }
    return primes;
}

我的顾虑

我担心的是,我创建的数组对于该方法将返回的最终元素数而言太大。问题是我不知道正确猜出小于指定数量的质数的好方法。

焦点

程序就是这样使用数组的。这是我要改进的地方。

  1. 我创建一个临时数组,该数组的大小足以容纳每个小于限制的数字。
  2. 我生成素数,同时统计生成的素数。
  3. 我制作了一个新的数组,该数组是仅容纳素数的正确维度。
  4. 我将每个素数从巨大数组复制到正确维度的数组。
  5. 返回正确维度的数组,其中仅包含我生成的素数。

问题

  1. 我是否可以(一次)复制temp[]具有非零元素的整个块,primes[] 而不必遍历两个数组并一次又一次地 复制元素?
  2. 是否有任何数据结构的行为都像原始数组一样,可以随着添加元素而增长,而不是在实例化时需要一个维?与使用原始数组相比,性能损失是多少?

版本2(感谢Jon Skeet):

private static int [] generatePrimes(int max) {
    int [] temp = new int [max];
    temp [0] = 2;
    int index = 1;
    int prime = 1;
    boolean isPrime = false;
    while((prime += 2) <= max) {
        isPrime = true;
        for(int i = 0; i < index; i++) {
            if(prime % temp [i] == 0) {
                isPrime = false;
                break;
            }
        }
        if(isPrime) {
            temp [index++] = prime;
        }
    }
    return Arrays.copyOfRange(temp, 0, index);
}

使用Erastosthenes筛网的版本3

private static int [] generatePrimes(int max) {
    boolean[] isComposite = new boolean[max + 1];
    for (int i = 2; i * i <= max; i++) {
        if (!isComposite [i]) {
            for (int j = i; i * j <= max; j++) {
                isComposite [i*j] = true;
            }
        }
    }
    int numPrimes = 0;
    for (int i = 2; i <= max; i++) {
        if (!isComposite [i]) numPrimes++;
    }
    int [] primes = new int [numPrimes];
    int index = 0;
    for (int i = 2; i <= max; i++) {
        if (!isComposite [i]) primes [index++] = i;
    }
    return primes;
}

问题答案:

通过将数组的每个元素与每个可能的因素进行比较来找到质数的方法效率低下。您可以一次对整个阵列进行Eratosthenes筛分,以极大地改善它。除了进行少得多的比较外,它还使用加法而不是除法。除法要慢得多。



 类似资料:
  • 为了澄清,这与Eratosthenes的问题Sieve-Finding Primes Python不同,因为我不想在两个数字之间生成素数,但我想检查一个数字是否是素数。 我做了下面的代码来确定一个数字是否是素数。然后我听说了埃拉托色尼算法的筛子,它显然更快,但我不知道如何在下面的代码中编写它? 你们能帮帮我吗?

  • 问题内容: 我已经可以存储所有32位质数,并且 我想用它们来生成一些64位质数 。即使对逻辑和编译进行了优化,使用试验划分也太慢了。 我正在尝试修改Eratosthenes的筛网以使用预定义列表,如下所示: 在数组A中从2到4294967291 在数组B中从2 ^ 32到X inc减1 找到C,它是当前素数的第一个倍数。 从C标记开始并以当前素数跳至X。 转到1。 问题是使用模数查找素数的第3步,

  • 问题内容: 我正在使用既包含数字又包含字母数字或仅包含数字但不仅仅包含字母的字符串。为了测试错误匹配,我需要检查字符串是否至少包含一位数字,如果没有,则输出错误消息。我一直在使用以下代码: 有没有更Python化或更简单的方法可以做到这一点?另外,我不能仅检查字符串是否为字母数字,因为字符串可能包含各种符号(’-‘,空格等)。 问题答案: 这是正则表达式仅此而已的地方之一: 小样: 您可以使用@W

  • 我试图解决这个问题:“2520是最小的数字,可以被1到10的每个数字除,没有任何余数。 可以被1到20的所有数字整除的最小正数是多少?" 请不要告诉我答案,我真的很想自己解决。我只需要一个关于问题数学方面的建议。问题是每个周期添加一个不是一个好主意,因为这个过程太慢了。或者变量类型不长的问题? 我试图得到(1到10)和(1到17)之间所有数字的等分数,该算法运行良好。 我期望得到特定的整数,但得到

  • 我是新来的mongo。我有以下收藏。 文件: 请求: 文档集合中的typeId是文档类型的id,其中请求中的typeId是也可以为空的外部字段。如何获得以下输出。