소수 찾기
문제정의
숫자 카드가 주어지고, 각 숫자 카드를 조합하여 나온 숫자 중 소수가 몇 개 있는지 계산하는 문제이다.
문제풀이
전체 코드는 다음과 같다. 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49import java.util.*;
public class FindPrimeNum
{
    //프로그래머스 문제풀이 level2 소수 찾기
    public static void main(String[] args) {
        String numbers = "17";
        Set<Integer> set = new HashSet<Integer>();
        StringBuilder buff = new StringBuilder();
        buff.append(numbers);
        for(int i = 1; i <= numbers.length(); i++)
        {
            findKDigitPrimeNum("", 0, set, i, buff);
        }
        System.out.println(set.size());
    }
    public static void findKDigitPrimeNum(String s, int size, Set<Integer> set, int k, StringBuilder buff)
    {
        if(size == k)
        {
            int n = Integer.parseInt(s);
            if(n <= 1)
                return;
            for(int i = 2; i <= Math.sqrt(n); i++)
            {
                if(n%i == 0)
                    return;
            }
            set.add(n);
        }
        else
        {
            
            for(int i = 0; i < buff.length(); i++)
            {
                StringBuilder str = new StringBuilder();
                char c = buff.charAt(i);
                str.append(s);
                str.append(c);
                findKDigitPrimeNum(str.toString(), size+1, set, k, buff.delete(i, i+1));
                str.delete(str.length()-1, str.length());
                buff.insert(i, c);
            }
        }
            
    }
}
위 과정을 코드로 담은 것이 위에 코드다 여기서 1번 함수에 대한 세부설명을 하겠다. 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30public static void findKDigitPrimeNum(String s, int size, Set<Integer> set, int k, StringBuilder buff)
{
    if(size == k)
    {
        int n = Integer.parseInt(s);
        if(n <= 1)
            return;
        for(int i = 2; i <= Math.sqrt(n); i++)
        {
            if(n%i == 0)
                return;
        }
        set.add(n);
    }
    else
    {
            
        for(int i = 0; i < buff.length(); i++)
        {
            StringBuilder str = new StringBuilder();
            char c = buff.charAt(i);
            str.append(s);
            str.append(c);
            findKDigitPrimeNum(str.toString(), size+1, set, k, buff.delete(i, i+1));
            str.delete(str.length()-1, str.length());
            buff.insert(i, c);
        }
    }
            
}
시간복잡도는 문자열의 길이를 n이라 할 때, \(O(n^{n+1})\)이다.
테스트
완전 탐색이라 시간복잡도차 최악을 도는 것을 볼 수 있다. 이러한 문제는 보통 테스트 케이스의 수가 상대적으로 작다. 이런 문제가 나올 땐 효율성에 겁내지 말고 일단 해보는 것이 중요하다.