📜  对于非常大的数,检查一个数是素数、半素数还是复合数

📅  最后修改于: 2021-09-22 10:55:27             🧑  作者: Mango

给定一个非常大的数N (> 150),任务是检查这个数是素数、半素数还是复合数。

例子:

方法:

  • 可以观察到,如果 n 是素数,则 n+1 或 n-1 将被 6 整除
  • 如果一个数 n 存在使得 n+1 和 n-1 都不能被 6 整除,那么 n 不是素数
  • 如果一个数 n 存在使得 n+1 或 n-1 可以被 6 整除,那么 n 要么是素数要么是半素数
  • 为了区分素数和半素数,使用以下方法:
    • 如果 N 是半素数,则
      N = p*q  ....................(1)
      where p & q are primes.
      
    • 然后从哥德巴赫猜想
      p + q must be even
      i.e, p + q = 2*n for any positive integer n
      
    • 因此求解 p & q 将给出
      p = n - sqrt(n2 - N)
      q = n + sqrt(n2 - N)
      
    • 令 n 2 – N 为完全平方数,则
      n2 - N = m2, .................(2)
      for any positive integer m 
      
    • 求解方程(1)和(2)我们得到
      m = (q-p)/2
      n = (p+q)/2
      
    • 现在,如果等式 (1) 和 (2) 在某个时刻相遇,则存在一对 (p, q) 使得数字 N 是半素数,否则 N 是素数。
  • 方程(2)形成勾股三元组
  • 预期的解决方案在图表上有所不同

伪代码:

  • 输入一个数字 N,如果N – 1N + 1不能被 6 整除,则数字 N不是质数。否则它是素数或半素数
  • 如果 n-1 或 n+1 可被 6 整除,则在范围 (sqrt(N) + 1, N) 中迭代并通过以下公式找到一对 (p, q) 使得p*q = N
    p = i - sqrt(i*i - N)
    q = n/p
    where i = index in range(sqrt(N) + 1, N)
  • 如果 p*q = N 则 N 为半素数,否则为素数

下面是上述方法的实现:

Java
import static java.lang.Math.sqrt;
  
public class Primmefunc {
  
    public static void prime(long n)
    {
        int flag = 0;
  
        // checking divisibilty by 6
        if ((n + 1) % 6 != 0 && (n - 1) % 6 != 0) {
            System.out.println("Not Prime");
        }
        else {
  
            // breakout if number is perfect square
            double s = sqrt(n);
            if ((s * s) == n) {
                System.out.println("Semi-Prime");
            }
            else {
                long f = (long)s;
                long l = (long)((f * f));
  
                // Iterating over to get the
                // closest average value
                for (long i = f + 1; i < l; i++) {
  
                    // 1st Factor
                    long p = i - (long)(sqrt((i * i) - (n)));
  
                    // 2nd Factor
                    long q = n / p;
  
                    // To avoid Convergence
                    if (p < 2 || q < 2) {
                        break;
                    }
  
                    // checking semi-prime condition
                    if ((p * q) == n) {
                        flag = 1;
                        break;
                    }
  
                    // If convergence found
                    // then number is semi-prime
                    else {
  
                        // convergence not found
                        // then number is prime
                        flag = 2;
                    }
                }
  
                if (flag == 1) {
                    System.out.println("Semi-Prime");
                }
                else if (flag == 2) {
  
                    System.out.println("Prime");
                }
            }
        }
    }
  
    public static void main(String[] args)
    {
        // Driver code
        // Entered number should be greater
        // than 300 to avoid Convergence of
        // second factor to 1
        prime(8179);
        prime(7894561);
        prime(90000000);
        prime(841);
        prime(22553);
        prime(1187);
    }
//written by Rushil Jhaveri
}


CPP
#include
using namespace std ;
  
void prime(long n)
{
    int flag = 0;
  
    // checking divisibilty by 6
    if ((n + 1) % 6 != 0 && (n - 1) % 6 != 0) 
    {
        cout << ("Not Prime") << endl;
    }
    else
    {
  
        // breakout if number is perfect square
        double s = sqrt(n);
        if ((s * s) == n) 
        {
            cout<<("Semi-Prime")<


Python3
def prime(n):
    flag = 0;
  
    # checking divisibilty by 6
    if ((n + 1) % 6 != 0 and (n - 1) % 6 != 0):
        print("Not Prime");
    else:
  
        # breakout if number is perfect square
        s = pow(n, 1/2);
        if ((s * s) == n):
            print("Semi-Prime");
        else:
            f = int(s);
            l = int(f * f);
  
            # Iterating over to get the
            # closest average value
            for i in range(f + 1, l):
  
                # 1st Factor
                p = i - (pow(((i * i) - (n)), 1/2));
  
                # 2nd Factor
                q = n // p;
  
                # To avoid Convergence
                if (p < 2 or q < 2):
                    break;
                  
                # checking semi-prime condition
                if ((p * q) == n):
                    flag = 1;
                    break;
                  
                # If convergence found
                # then number is semi-prime
                else:
  
                    # convergence not found
                    # then number is prime
                    flag = 2;
                  
            if (flag == 1):
                print("Semi-Prime");
            elif(flag == 2):
  
                print("Prime");
              
# Driver code
if __name__ == '__main__':
  
    # Entered number should be greater
    # than 300 to avoid Convergence of
    # second factor to 1
    prime(8179);
    prime(7894561);
    prime(90000000);
    prime(841);
    prime(22553);
    prime(1187);
  
# This code is contributed by 29AjayKumar


C#
using System;
public class Primmefunc 
{
  
    public static void prime(long n)
    {
        int flag = 0;
  
        // checking divisibilty by 6
        if ((n + 1) % 6 != 0 && (n - 1) % 6 != 0)
        {
            Console.WriteLine("Not Prime");
        }
        else 
        {
  
            // breakout if number is perfect square
            double s = Math.Sqrt(n);
            if ((s * s) == n)
            {
                Console.WriteLine("Semi-Prime");
            }
            else 
            {
                long f = (long)s;
                long l = (long)((f * f));
  
                // Iterating over to get the
                // closest average value
                for (long i = f + 1; i < l; i++) 
                {
  
                    // 1st Factor
                    long p = i - (long)(Math.Sqrt((i * i) - (n)));
  
                    // 2nd Factor
                    long q = n / p;
  
                    // To avoid Convergence
                    if (p < 2 || q < 2) 
                    {
                        break;
                    }
  
                    // checking semi-prime condition
                    if ((p * q) == n)
                    {
                        flag = 1;
                        break;
                    }
  
                    // If convergence found
                    // then number is semi-prime
                    else
                    {
  
                        // convergence not found
                        // then number is prime
                        flag = 2;
                    }
                }
  
                if (flag == 1) 
                {
                    Console.WriteLine("Semi-Prime");
                }
                else if (flag == 2)
                {
                    Console.WriteLine("Prime");
                }
            }
        }
    }
  
    // Driver code
    public static void Main(String[] args)
    {
        // Entered number should be greater
        // than 300 to avoid Convergence of
        // second factor to 1
        prime(8179);
        prime(7894561);
        prime(90000000);
        prime(841);
        prime(22553);
        prime(1187);
    }
}
  
// This code is contributed by 29AjayKumar


输出:
Prime
Semi-Prime
Not Prime
Semi-Prime
Semi-Prime
Prime

时间复杂度: O(N)

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程