🧩 Algorithm/κ°œλ… 및 자료ꡬ쑰

[μ•Œκ³ λ¦¬μ¦˜] μ—λΌν† μŠ€ν…Œλ„€μŠ€μ˜ 체

devCloud 2023. 9. 23. 17:28
728x90

μ—λΌν† μŠ€ν…Œλ„€μŠ€μ˜ μ²΄λž€?

μ†Œμˆ˜λ₯Ό μ°ΎλŠ” λ°©λ²•μœΌλ‘œ, κ³ λŒ€ 그리슀 μˆ˜ν•™μž μ—λΌν† μŠ€ν…Œλ„€μŠ€κ°€ λ°œκ²¬ν–ˆλ‹€. 이 μ•Œκ³ λ¦¬μ¦˜μ„ μ‚¬μš©ν•˜μ§€ μ•Šκ³  λ‹¨μˆœνžˆ μ†Œμˆ˜λ₯Ό κ΅¬ν•˜λ €κ³  ν•  λ•Œ μ‹œκ°„μ΄ 였래 κ±Έλ¦¬λ―€λ‘œ μ†Œμˆ˜λ₯Ό κ΅¬ν•˜κ³ μž ν•  λ•Œ μ—λΌν† μŠ€ν…Œλ„€μŠ€μ˜ 체 μ•Œκ³ λ¦¬μ¦˜μ„ μ‚¬μš©ν•˜λŠ” 것이 훨씬 νš¨μœ¨μ μ΄λ‹€.

 

μ†Œμˆ˜κ°€ κ΅¬ν•΄μ§€λŠ” κ³Όμ •

Alogrithm

  1. 2λΆ€ν„° μ†Œμˆ˜λ₯Ό κ΅¬ν•˜κ³ μž ν•˜λŠ” κ΅¬κ°„μ˜ λͺ¨λ“  수λ₯Ό λ‚˜μ—΄ν•œλ‹€. κ·Έλ¦Όμ—μ„œ νšŒμƒ‰ μ‚¬κ°ν˜•μœΌλ‘œ 두λ₯Έ μˆ˜λ“€μ΄ 여기에 ν•΄λ‹Ήν•œλ‹€.
  2. 2λŠ” μ†Œμˆ˜μ΄λ―€λ‘œ 였λ₯Έμͺ½μ— 2λ₯Ό μ“΄λ‹€. (λΉ¨κ°„μƒ‰μœΌλ‘œ ν‘œμ‹œ)
  3. 자기 μžμ‹ μ„ μ œμ™Έν•œ 2의 배수λ₯Ό λͺ¨λ‘ μ§€μš΄λ‹€. (μ„ ν™μƒ‰μœΌλ‘œ ν‘œμ‹œ)
  4. λ‚¨μ•„μžˆλŠ” 수 κ°€μš΄λ° 2의 λ‹€μŒμΈ 3은 μ†Œμˆ˜μ΄λ―€λ‘œ 였λ₯Έμͺ½μ— 3을 μ“΄λ‹€. (μ΄ˆλ‘μƒ‰μœΌλ‘œ ν‘œμ‹œ)
  5. 자기 μžμ‹ μ„ μ œμ™Έν•œ 3의 배수λ₯Ό λͺ¨λ‘ μ§€μš΄λ‹€. (μ—°μ΄ˆλ‘μœΌλ‘œ ν‘œμ‹œ)
  6. μœ„μ˜ 과정을 λ°˜λ³΅ν•˜λ©΄ κ΅¬ν•˜κ³ μž ν•˜λŠ” κ΅¬κ°„μ˜ λͺ¨λ“  μ†Œμˆ˜κ°€ λ‚¨κ²Œ λœλ‹€.

Python

방법 1 (ν•¨μˆ˜λ‘œ μ •μ˜)

def prime_list(n):
    # μ—λΌν† μŠ€ν…Œλ„€μŠ€μ˜ 체 μ΄ˆκΈ°ν™”: n개 μš”μ†Œμ— True μ„€μ •(μ†Œμˆ˜λ‘œ κ°„μ£Ό)
    sieve = [True] * n

    # n의 μ΅œλŒ€ μ•½μˆ˜κ°€ sqrt(n) μ΄ν•˜μ΄λ―€λ‘œ i=sqrt(n)κΉŒμ§€ 검사
    m = int(n ** 0.5)
    for i in range(2, m + 1):
        if sieve[i] == True:           # iκ°€ μ†Œμˆ˜μΈ 경우
            for j in range(i+i, n, i): # i이후 i의 λ°°μˆ˜λ“€μ„ False νŒμ •
                sieve[j] = False

    # μ†Œμˆ˜ λͺ©λ‘ μ‚°μΆœ
    return [i for i in range(2, n) if sieve[i] == True]

방법 2 

n = int(input())
a = [True] * (n + 1)
m = int(n**0.5)

for i in range(2, m + 1):
    if a[i] == True:
        for j in range(i + i, n + 1, i):
            a[j] = False

print([i for i in range(2, n + 1) if a[i] == True])

βœ’ n**0.5 or sqrt(n) 을 ν•˜λŠ” 이유

sqrt(n) μ΄ν•˜μ˜ 숫자만 ν•˜λ©΄ λ˜λŠ”λ°, λ§Œμ•½ n이 μ†Œμˆ˜μ΄κ³  n보닀 μž‘μ€ ν•©μ„±μˆ˜ m = ab라고 ν•˜λ©΄ a와 b λ‘˜ 쀑 ν•˜λ‚˜λŠ” sqrt(n)보닀 무쑰건 μž‘κΈ° λ•Œλ¬Έμ΄λ‹€.

 

μžμ„Έν•œ μ„€λͺ… μ•„λž˜ 링크

 

μ—λΌν† μŠ€ν…Œλ„€μŠ€μ˜ 체 ν˜Ήμ€ μ†Œμˆ˜νŒμ • μ‹œ 제곱근 κΉŒμ§€λ§Œ ν™•μΈν•˜λ©΄ λ˜λŠ” 이유

ν”νžˆ μ—λΌν† μŠ€ν…Œλ„€μŠ€μ˜ 체λ₯Ό μ‚¬μš©ν•΄ n μ΄ν•˜μ˜ λͺ¨λ“  μ†Œμˆ˜λ₯Ό κ΅¬ν•˜λ €κ³  ν•  λ•Œ, 효율적으둜 κ΅¬ν•˜κΈ° μœ„ν•΄ n의 제곱근( sqrt(n) ) κΉŒμ§€λ§Œ ν™•μΈν•˜κ³€ ν•œλ‹€. 1λ…„μ „μ―€μ—” nκΉŒμ§€ λ‹€ ν™•μΈν•˜κ±°λ‚˜, μ’€ 머리 μ“΄λ‹€κ³  n/

nahwasa.com

C/C++

void Eratos(int n)
{
    /*  만일 n이 1보닀 μž‘κ±°λ‚˜ κ°™μœΌλ©΄ ν•¨μˆ˜ μ’…λ£Œ */
    if (n <= 1) return;

    /*	2λΆ€ν„° nκΉŒμ§€ n-1개λ₯Ό μ €μž₯ν•  수 μžˆλŠ” λ°°μ—΄ ν• λ‹Ή
		λ°°μ—΄ μ°Έμ‘° λ²ˆν˜Έμ™€ μ†Œμˆ˜μ™€ μΌμΉ˜ν•˜λ„λ‘ λ°°μ—΄μ˜ ν¬κΈ°λŠ”
		n+1 길이만큼 ν• λ‹Ή(인덱슀 번호 0κ³Ό 1은 μ‚¬μš©ν•˜μ§€ μ•ŠμŒ)	*/
	bool* PrimeArray = new bool[n + 1];

	/*  λ°°μ—΄μ΄ˆκΈ°ν™”: μ²˜μŒμ—” λͺ¨λ‘ μ†Œμˆ˜λ‘œ 보고 true값을 쀌	*/
	for (int i = 2; i <= n; i++)
	    PrimeArray[i] = true;

	/*	μ—λΌν† μŠ€ν…Œλ„€μŠ€μ˜ 체에 맞게 μ†Œμˆ˜λ₯Ό ꡬ함
		만일, PrimeArray[i]κ°€ true이면 i μ΄ν›„μ˜ i λ°°μˆ˜λŠ” μ•½μˆ˜λ‘œ iλ₯Ό
		κ°€μ§€κ³  μžˆλŠ” 것이 λ˜λ―€λ‘œ i μ΄ν›„μ˜ i λ°°μˆ˜μ— λŒ€ν•΄ false값을 μ€€λ‹€.
		PrimeArray[i]κ°€ false이면 iλŠ” 이미 μ†Œμˆ˜κ°€ μ•„λ‹ˆλ―€λ‘œ i의 배수 μ—­μ‹œ
		μ†Œμˆ˜κ°€ μ•„λ‹ˆκ²Œ λœλ‹€. κ·ΈλŸ¬λ―€λ‘œ 검사할 ν•„μš”λ„ μ—†λ‹€.
λ˜ν•œ i*k (k < i) κΉŒμ§€λŠ” 이미 κ²€μ‚¬λ˜μ—ˆμœΌλ―€λ‘œ jμ‹œμž‘ 값은 i*2μ—μ„œ i*i둜 κ°œμ„ ν•  수 μžˆλ‹€.
	*/
	for (int i = 2; i * i <= n; i++)
	{
		if (PrimeArray[i])
			for (int j = i * i; j <= n; j += i)
			    PrimeArray[j] = false;
	}

	// μ΄ν›„μ˜ μž‘μ—… ...
}

JAVA

import java.util.*;

class Main {
    public static int n = 1000; // 2λΆ€ν„° 1,000κΉŒμ§€μ˜ λͺ¨λ“  μˆ˜μ— λŒ€ν•˜μ—¬ μ†Œμˆ˜ νŒλ³„
    public static boolean[] arr = new boolean[n + 1];

    public static void main(String[] args) {
        Arrays.fill(arr, true); // μ²˜μŒμ—” λͺ¨λ“  μˆ˜κ°€ μ†Œμˆ˜(True)인 κ²ƒμœΌλ‘œ μ΄ˆκΈ°ν™”(0κ³Ό 1은 μ œμ™Έ)
        // μ—λΌν† μŠ€ν…Œλ„€μŠ€μ˜ 체 μ•Œκ³ λ¦¬μ¦˜ μˆ˜ν–‰
        // 2λΆ€ν„° n의 μ œκ³±κ·ΌκΉŒμ§€μ˜ λͺ¨λ“  수λ₯Ό ν™•μΈν•˜λ©°
        for (int i = 2; i <= Math.sqrt(n); i++) {
            // iκ°€ μ†Œμˆ˜μΈ 경우(남은 수인 경우)
            if (arr[i] == true) {
                // iλ₯Ό μ œμ™Έν•œ i의 λͺ¨λ“  배수λ₯Ό μ§€μš°κΈ°
                int j = 2;
                while (i * j <= n) {
                    arr[i * j] = false;
                    j += 1;
                }
            }
        }
        // λͺ¨λ“  μ†Œμˆ˜ 좜λ ₯
        for (int i = 2; i <= n; i++) {
            if (arr[i]) System.out.print(i + " ");
        }
    }
}

β€» 좜처 https://ko.wikipedia.org/wiki/%EC%97%90%EB%9D%BC%ED%86%A0%EC%8A%A4%ED%85%8C%EB%84%A4%EC%8A%A4%EC%9D%98_%EC%B2%B4

728x90