Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 如何在O(n)时间复杂度下实现Eratosthenes的筛选?_Algorithm_Time Complexity_Primes_Sieve Of Eratosthenes - Fatal编程技术网

Algorithm 如何在O(n)时间复杂度下实现Eratosthenes的筛选?

Algorithm 如何在O(n)时间复杂度下实现Eratosthenes的筛选?,algorithm,time-complexity,primes,sieve-of-eratosthenes,Algorithm,Time Complexity,Primes,Sieve Of Eratosthenes,在O(n*log(log(n))时间复杂度中,有一个寻找高达n的素数的算法的实现。我们如何在O(n)时间复杂度中实现它呢?好吧,如果算法是O(n*log(n)),通常不改变算法就做不到更好 复杂性是O(n*log(n)),但您可以在时间和资源之间进行权衡:通过确保O(log(n))计算节点并行运行,可以在O(n)中完成这项工作 希望我没有做你的家庭作业…你可以进行埃拉托斯烯的筛选,以确定哪些数字在[2,n]时间O(n)范围内是素数,如下所示: 对于区间[2,n]中的每个数x,我们计算x的最小素

O(n*log(log(n))
时间复杂度中,有一个寻找高达
n
的素数的算法的实现。我们如何在
O(n)
时间复杂度中实现它呢?

好吧,如果算法是O(n*log(n)),通常不改变算法就做不到更好

复杂性是O(n*log(n)),但您可以在时间和资源之间进行权衡:通过确保O(log(n))计算节点并行运行,可以在O(n)中完成这项工作


希望我没有做你的家庭作业…

你可以进行埃拉托斯烯的筛选,以确定哪些数字在
[2,n]
时间
O(n)
范围内是素数,如下所示:

  • 对于区间
    [2,n]
    中的每个数
    x
    ,我们计算
    x
    的最小素数因子。为了实现,这可以通过保持一个数组来轻松实现,比如
    MPF[]
    ,其中
    MPF[x]
    表示
    x
    的最小素数因子。最初,对于每个整数
    x
    ,应将
    MPF[x]
    设置为等于零。随着算法的进行,此表将被填充

  • 现在我们使用for循环,从
    i=2
    迭代到
    i=n
    (包括在内)。如果我们遇到一个
    MPF[i]的数字
    等于
    0
    ,然后我们立即得出结论,
    i
    是素数,因为它没有最小素数因子。在这一点上,我们通过将
    i
    插入列表将其标记为素数,并将
    MPF[i]
    设置为等于
    i
    。相反,如果
    MPF[i]
    不等于
    0
    ,那么我们知道
    i
    与最小素因子的组合等于
    MPF[i]

  • 在每次迭代中,在我们检查了
    MPF[i]
    之后,我们执行以下操作:计算每个素数
    p\u j
    小于或等于
    MPF[i]
    的数
    y\u j=i*p\u j
    ,并将
    MPF[y\u j]
    设置为等于
    p\u j

这似乎是违反直觉的——为什么运行时<代码> o(n)< /C>?如果我们有两个嵌套循环?关键思想是每个值都设置为一个,所以运行时是代码> O(n)< /代码>。这给出了一个C++实现,我在下面提供:

const int N = 10000000;
int lp[N+1];
vector<int> pr;

for (int i=2; i<=N; ++i) {
    if (lp[i] == 0) {
        lp[i] = i;
        pr.push_back (i);
    }
    for (int j=0; j<(int)pr.size() && pr[j]<=lp[i] && i*pr[j]<=N; ++j)
        lp[i * pr[j]] = pr[j];
}
const int N=10000000;
int-lp[N+1];
载体pr;

对于(int i=2),为什么你要标记C++和java,就像说“用任何语言给我代码”?如果你问一个算法不标注任何语言。如果你问一个具体的实现,请告诉我们你做了什么,只标注适当的语言。我得到了。谢谢:当然,它不可伸缩。如果您认为它不正确,请提供实际运行时间,例如
n1=1B
n2=1.5B
,以便我们可以计算as
log(t2/t1)/log(1.5)
。用于比较,简单的位压缩非分段(连续)按赔率筛选埃拉托什尼在该范围内表现出~n^1.06行为(这是旧的计时,当前的ideone肯定会更快,但增长顺序不会有太大变化).除了日志之外,你想详细说明一下吗?不是所有的东西都是可并行的。不是每个并行都能提高复杂性。可用CPU的数量通常是有限的和固定的。如果有这样的需要,线程之间的通信会有成本。等等。等等。所有这些都必须针对给定的算法进行专门解决。其他是的,但筛子很容易并行化。因为没有给出代码,这看起来更像是计算机科学讲座中的一个理论问题。当我学习时,我们可以假设一台足够大的机器。实际上,即使是O(n^2)也可以比O(n)快得多即使对于n的大值,在它转变之前,那么给出了什么-这是一个理论问题的理论答案。没有固定数量的资源(如可用的内核)会改变复杂性一点点。啊,你太实际了…;-)