회고록/Java dataStructure&Algorithm

소수(prime number) 인지 아닌지 확인.

sehunbang 2024. 3. 11. 11:20

소수(素數, 발음: [소쑤], 문화어: 씨수, 영어: prime number)는 1보다 큰 자연수 중 1과 자기 자신만을 약수로 가지는 수다.

 

소수 를 구하는 여러가지 방법들있고 어떻게 작동 하는지 + 어떤게 효율적인지 확인 하겠습니다.

 

1. good  (별로 추천 안함 밑에 better 을 보세요)

제일 간단하고 설명 하기 쉬운 논리의 방법

static boolean isPrime(int n)
{
  // Corner case
  if (n <= 1)
    return false;

  // Check from 2 to n-1
  for (int i = 2; i < n; i++)
    if (n % i == 0)
      return false;

  return true;
}

Time complexity(시간 복잡도):  O(n) 

Space complexity (공간 복잡도) : O(1)

 

하지만 사실상 n 의 절반 까지만 나누어 봐도 소수 인지 아닌지 확인 가능 하기 때문에 개선이 가능 하다. 

(i 로 나눌수 있으면 i*2 로 나누어 지는거 는 같기 때문에).

static boolean isPrime(int n)
{
  // Corner case
  if (n <= 1)
    return false;

  // Check from 2 to n/2
  for (int i = 2; i <= n / 2; i++)
    if (n % i == 0)
      return false;

  return true;
}

Time complexity(시간 복잡도):  O(n) 

Space complexity (공간 복잡도) : O(1)

 

 

 

2. better

n까지 확인하는 대신

 √n까지 확인 하는 수가 있습니다.

n의 더 큰 인수는 이미 확인된 작은 인수의 배수여야 하기 때문.

public boolean isPrime(long n) {
  if (n == 1) return false;
  if (n == 2) return true;

  int count = 0;

  for (long i = 2; i <= Math.sqrt(n); i++) {
    if (n % i == 0) return false;
  }

  return true;
}

 

원리는 n 의 약수는 항상 제곱근보다 작은 수가 존재하며 그 작은 수는 제곱근보다 큰 수와 짝을 이룬다.

 

예를 들어 100의 약수를 구하면 다음과 같다.
1,2,4,5,10,20,25,50,100
100의 제곱근은 10이기 때문에 10을 기준으로 10보다 작은 약수는 “1,2,4,5” 가 있고 각각의 짝 (곱해서 100이 되는)은 “100,50,25,20” 이므로
제곱근보다 작은 수들 중에 약수가 존재하지 않는 다면 큰 수에서도 존재하지 않는다.

 

Time complexity: O(√n)

Space complexity: O(1)

 

 

 

더 효율적인 방법은 n이 2 또는 3으로 나누어지는지 테스트한 

다음 6k ± 1 ≤ √n 형식의 모든 숫자를 확인하는 것입니다. 

이 접근 방식은 최대 √n까지의 모든 숫자를 테스트하는 것보다 3배 빠릅니다.

 

static boolean isPrime(int n)
{
  // Corner case
  if (n <= 1)
    return false;

  if (n == 2 || n == 3)
    return true;

  if (n % 2 == 0 || n % 3 == 0)
    return false;

  for (int i = 5; i <= Math.sqrt(n); i = i + 6)
    if (n % i == 0 || n % (i + 2) == 0)
      return false;

  return true;
}

 

 

Time complexity: O(√n)

Space complexity: O(1)