📜  素数分解的试验划分算法

📅  最后修改于: 2021-04-29 04:23:23             🧑  作者: Mango

在本文中,讨论了检查数字是否为质数的试算法。给定数字N,任务是检查数字是否为质数。

例子:

天真的方法:根据定义,素数是大于1的整数,只能被1及其自身整除。因此,我们初始化一个从2到N – 1的循环,并检查可除性。以下是该方法的伪代码:

N <- input
initialise: i <- 2
while(i ≤ N - 1):
    if(N % i == 0):
        return "Composite"
return "Prime" 

时间复杂度分析:

  • 对于任何给定的数字N ,while循环运行N – 2次。因此,while循环的时间复杂度为O(N)
  • 可除性检查是在固定时间内完成的。因此,while循环中if条件的时间复杂度为O(1)
  • 因此,上述方法的总时间复杂度为O(N)

审判分割法:通过审判分割法的概念可以更有效地执行素数检查。当处理整数分解时,Trial Division方法是关键但最简单的分解技术之一。

观察:上述方法适用于观察到任何数字N的最大因数始终小于或等于平方根(N)。该结论可以通过以下方式得出:

  • 从学校算法来看,众所周知的事实是,任何复合数都是由两个或多个质数构成的。
  • N的因子为n1,n2,依此类推。仅当数量N存在两个因子n1n2时,这些因子才最大。
  • 因此,假设n1n2是数量N的两个最大因子。仅当n1和n2相等时,这些数字n1n2才能最大。
  • n1 = n2 = n 。因此, N = n * n 。因此,N的最大可能因数是平方根(N)

方法:根据以上观察,该算法的方法很简单。这个想法不是检查直到N – 1的一个因数,我们只检查直到平方根(N)

下面是上述方法的实现:

C++
// CPP implementation of
// Trial Division Algorithm
#include 
  
using namespace std;
  
// Function to check if a number is
// a prime number or not
int TrialDivision(int N){
  
    // Initializing with the value 2
    // from where the number is checked
    int i = 2;
  
    // Computing the square root of
    // the number N
    int k = ceil(sqrt(N));
  
    // While loop till the
    // square root of N
    while(i<= k){
  
        // If any of the numbers between
        // [2, sqrt(N)] is a factor of N
        // Then the number is composite
        if(N % i == 0)
            return 0;
        i += 1;
    }
  
    // If none of the numbers is a factor,
    // then it is a prime number
    return 1;
}
  
// Driver code
int main()
{
    int N = 49;
    int p = TrialDivision(N);
  
    // To check if a number is a prime or not
    if(p)
        cout << ("Prime");
    else
        cout << ("Composite");
  
    return 0;
}
  
// This code is contributed by mohit kumar 29


Java
// Java implementation of
// Trial Division Algorithm
import java.util.*;
   
class GFG{
    
// Function to check if a number is
// a prime number or not
static int TrialDivision(int N){
  
    // Initializing with the value 2
    // from where the number is checked
    int i = 2;
  
    // Computing the square root of
    // the number N
    int k =(int) Math.ceil(Math.sqrt(N));
  
    // While loop till the
    // square root of N
    while(i<= k){
  
        // If any of the numbers between
        // [2, sqrt(N)] is a factor of N
        // Then the number is composite
        if(N % i == 0)
            return 0;
        i += 1;
    }
  
    // If none of the numbers is a factor,
    // then it is a prime number
    return 1;
}
  
// Driver Code
public static void main(String[] args)
{
   
    int N = 49;
    int p = TrialDivision(N);
  
    // To check if a number is a prime or not
    if(p != 0) 
        System.out.print("Prime");
    else
        System.out.print("Composite");
  
}
}
  
// This code is contributed by shivanisinghss2110


Python3
# Python3 implementation of 
# Trial Division Algorithm
  
# Function to check if a number is
# a prime number or not 
def TrialDivision(N):
  
    # Initializing with the value 2 
    # from where the number is checked
    i = 2
  
    # Computing the square root of 
    # the number N
    k = int(N ** 0.5)
  
    # While loop till the 
    # square root of N
    while(i<= k):
  
        # If any of the numbers between 
        # [2, sqrt(N)] is a factor of N 
        # Then the number is composite
        if(N % i == 0):
            return 0
        i += 1
  
    # If none of the numbers is a factor,
    # then it is a prime number
    return 1
      
# Driver code
if __name__ == "__main__":
    N = 49
    p = TrialDivision(N)
  
# To check if a number is a prime or not
    if(p):
        print("Prime")
    else:
        print("Composite")


C#
// C# implementation of
// Trial Division Algorithm
using System;
  
class GFG{
  
// Function to check if a number is
// a prime number or not
static int TrialDivision(int N){
  
    // Initializing with the value 2
    // from where the number is checked
    int i = 2;
  
    // Computing the square root of
    // the number N
    int k =(int) Math.Ceiling(Math.Sqrt(N));
  
    // While loop till the
    // square root of N
    while(i<= k){
  
        // If any of the numbers between
        // [2, sqrt(N)] is a factor of N
        // Then the number is composite
        if(N % i == 0)
            return 0;
        i += 1;
    }
  
    // If none of the numbers is a factor,
    // then it is a prime number
    return 1;
}
  
// Driver Code
public static void Main()
{
  
    int N = 49;
    int p = TrialDivision(N);
  
    // To check if a number is a prime or not
    if(p != 0) 
        Console.Write("Prime");
    else
        Console.Write("Composite");
  
}
}
  
// This codee is contributed by AbhiThakur


输出:
Composite

时间复杂度分析:

  • while循环最多执行平方根(N)次。因此,while循环的时间复杂度为O(sqrt(N))
  • 所有if条件的运行时间都是恒定的。因此,if语句的时间复杂度为O(1)
  • 因此,总体时间复杂度为O(sqrt(N))

优化的试验划分方法:可以通过消除范围[2,K]中的所有偶数来进一步优化上述试验划分方法其中K =平方根(N),因为2是唯一的偶数素数。总体复杂度仍然保持不变,但是执行次数减少了一半。

注意:在Trial Division方法中进行的优化可能看起来很小,因为除了迭代次数外,该方法与Naive Approach几乎相似。但是,这极大地减少了较高N值的计算数量。这可以通过以下图表相对于算法的相应运行时间来绘制来说明: