【问题标题】:Time Complexity of this primality test function这个素数测试函数的时间复杂度
【发布时间】:2020-11-03 21:59:46
【问题描述】:

这个函数的时间复杂度是多少

bool prime(int n) {
    if(n <= 1) {
        return false;
    } else if(n <= 3) {
        return true;
    } else if(n % 2 == 0 || n % 3 == 0) {
        return false;
    } else {
        for(int i = 5; i * i <= n; i += 6) {
            if(n % i == 0 || n % (i + 2) == 0) {
                return false;
            }
        }
    }
    return true;
}

如果我不得不猜测,那将是

O(sqrt(log(n)))

【问题讨论】:

  • 我的印象是 O(n)?
  • 但只是 for 循环最多需要 O(sqrt(n))
  • 我认为丢失的界限是 O(sqrt(n)),而更严格的界限是 O(sqrt(n) * 1/6)。 不是专家,可能完全错了。
  • 请问日志是从哪里来的?
  • @MarkRansom 一旦知道,就很容易证明primes.utm.edu/notes/faq/six.html ;)

标签: c++ time-complexity big-o primality-test


【解决方案1】:

每个 if 都是常数时间。

for 循环一直执行到i * i 到达n 这意味着它被执行了sqrt(n) / 6 次。所以复杂度是O(sqrt(n))

它没有衡量素数的密度与1/log(n) 成正比(这可能是您解决方案中log(n) 的来源。

请注意,时间复杂度(无形容词)通常被认为是最差的时间复杂度:

Time complexity - Wikipedia

由于算法的运行时间在相同大小的不同输入之间可能会有所不同,因此通常会考虑worst-case time complexity,这是给定大小的输入所需的最长时间。不太常见且通常明确指定的是average-case complexity

在这种情况下,平均时间复杂度更难计算。当n 不是质数时,您必须证明平均循环终止的速度有多快。

【讨论】:

  • 但如果它是O(sqrt(n)),如果我将整数更改为长整数,并且我将 n 设置为1020100101111191,它运行得非常快。每秒钟,计算机应该平均运行大约10^8 个操作。这个数字有 16 位长,应该在大约 1 秒内运行,但它几乎立即运行,并告诉我它是质数。
  • 素数的密度确实很重要:当采用return false; 路径时,for 循环更早退出,从而降低了时间复杂度。您可以调用 O(sqrt(n)) 最坏情况复杂度,但我认为这不是有效的平均时间复杂度。
  • @Jeffrey 复杂性总是针对最坏的情况进行计算。所以在这种情况下,n 是素数。请注意,符号 O 表示渐近复杂度不会比那时慢。
  • 绝对不总是。 en.wikipedia.org/wiki/Average-case_complexity 在素性测试的情况下,当您知道大多数情况不会是最坏的情况时,考虑平均情况是有意义的。
猜你喜欢
  • 2013-10-29
  • 1970-01-01
  • 2020-12-03
  • 2017-09-11
  • 2023-02-03
  • 2011-08-07
  • 1970-01-01
  • 1970-01-01
  • 2015-11-29
相关资源
最近更新 更多