【问题标题】:Quickly telling if a number can be represented as the multiple of two primes?快速判断一个数字是否可以表示为两个素数的倍数?
【发布时间】:2021-11-20 09:18:18
【问题描述】:

假设您有 10e4 个数字。每个数字不超过 10e6。如果每个数字可以表示为两个素数的倍数,如何有效地检查它?

示例: 15 可以表示为 3 * 5。 6 可以表示为 2 * 3。 但是 8 不能用两个素数来表示。

【问题讨论】:

  • 你能举一些例子来说明你具体要找什么吗?
  • 在这种规模下,在当今的计算机上,您无需担心效率问题。审判分庭就可以了。
  • 示例:15 可以表示为 1 * 15。 很抱歉,1 不是质数 :) 相反,15 可以表示为 3 * 5

标签: algorithm number-theory


【解决方案1】:

如果你不需要知道素数,只要有可能:

您可以预先计算一个包含 10e6 个条目的布尔表,该表表示该数字是否可以表示为两个素数的倍数。

你可以在 O(1) 中查找每个数字。

创建表格需要一些时间,但可以提前完成。

【讨论】:

    【解决方案2】:

    您可以预先计算最多为 5e6 (list_of_primes) 的所有素数,并使用以下算法检查每个数字 n

    for prime in list_of_primes:
       x = n / prime
       
       if (x is in list_of_primes) and (x != prime) and (x*prime==n):
          return True
    
    return False
    

    此算法未优化,但您的尺寸应该可以正常工作。我也希望伪代码是可以理解的。

    编辑:素数列表的计算可以用埃拉托色尼筛法完成。

    【讨论】:

      【解决方案3】:

      (假设 x*x 形式的数字,其中 x 是素数,是可以的)

      我将调用valid 一个可以表示为2 个素数的乘积的数字。 如果一个数 x 是有效的,那么只有一个表示为 2 个素数 a 和 b 的乘积。事实上,x 的唯一除数是 1、a、b 和 x。

      因此,检查数字 x 是否有效的算法是取每个素数 a 小于或等于 sqrt(x),并查看是否除以 x。如果是,请检查 b = x/a 是否也是素数。如果是这种情况,则 x 有效,否则 x 无效。 记住素数列表确实可以加快这个过程。

      check_2_primes_representation(X):
          index = 0
          prime = list_of_prime[index]
          while(prime < sqrt(X))
              if(x mod prime == 0): # prime is a divisor of x
                  return is_prime(x/prime)
              index += 1
              prime = list-of_prime[index]
          return false
      

      查看此问题的另一种方法是生成所有有效数字的列表。这很容易做到,因为您只需要将素数相乘。一些技巧可以获得相当多的时间:你只需要一个数字一次,所以我们只做 a*b 形式的产品,其中 a sqrt(10e6) 时停止。

      valid_numbers:
         list = []
         for a in list_of_primes:
             if a > sqrt(10e6):
                 break #leave outer loop
             for b in primes_greater_than(a):
                 if a*b > 10e6:
                     break #leave inner loop
                 list.push(a*b)
          return list
      

      我在某些方面做得很快,请随时要求详细解释。

      【讨论】:

        【解决方案4】:

        在 1000 = sqrt(10^6) 下只有 168 个质数,在 10^6 下大约有 78,000 个。如果您的数字是两个素数的乘积,则较小的那个必须是 1000 以下的 168 个中的一个。

        假设大 N 是最大输入,小 n 是特定输入。这里 N = 10^6。

        将所有素数

        复杂性:

        给定一个最大值 N,并且要检查一个特定的 n

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-05-24
          • 1970-01-01
          • 2010-12-05
          • 1970-01-01
          • 2012-04-01
          • 1970-01-01
          相关资源
          最近更新 更多