완전 탐색
가능한 방법을 전부 만들어 보는 알고리즘으로 컴퓨터의 빠른 계산 속도를 이용하는 방법이다.
- Brute Force : for문과 if문을 이용하여 처음부터 끝까지 탐색하는 방법
 - 비트 마스크
 - 순열, 조합
 - 백트래킹
 - BFS
 
문제
문제 설명
한자리 숫자가 적힌 종이 조각이 흩어져있습니다. 흩어진 종이 조각을 붙여 소수를 몇 개 만들 수 있는지 알아내려 합니다.
각 종이 조각에 적힌 숫자가 적힌 문자열 numbers가 주어졌을 때, 종이 조각으로 만들 수 있는 소수가 몇 개인지 return 하도록 solution 함수를 완성해주세요.
** 제한사항 **
- numbers는 길이 1 이상 7 이하인 문자열입니다.
 - numbers는 0~9까지 숫자만으로 이루어져 있습니다.
 - 013은 0, 1, 3 숫자가 적힌 종이 조각이 흩어져있다는 의미입니다.
 
** 입출력 예 **
| numbers | return | 
|---|---|
| 17 | 3 | 
| 011 | 2 | 
** 입출력 예 설명 **
- 예제 #1
    
- [1, 7]으로는 소수 [7, 17, 71]를 만들 수 있습니다.
 
 - 예제 #2
    
- [0, 1, 1]으로는 소수 [11, 101]를 만들 수 있습니다.
 - 11과 011은 같은 숫자로 취급합니다.
 
 
문제 풀이
주어진 숫자로 만들 수 있는 모든 순열을 구하는게 어려웠다. 소수 찾는 건 금방 생각해 냈는데 이부분을 시간 내에 해결하지 못해서 결국 구글링해보았다…
여러 사람의 블로그를 보았는데 다들 코드가 엄청 길다.
    static boolean[] visited;
    static int ans;
    static char[] chs;
    static char[] select;   // 순열
    static HashSet<Integer> set;    // 소수 저장 (중복 제거)
    public static int solution(String numbers){
        chs = numbers.toCharArray();
        int size = numbers.length();
        visited = new boolean[size];
        ans = 0;
        set = new HashSet<>();
        
        for(int i=1; i<=size; i++){
            select = new char[i];
            perm(0, i, size);
        }
        return set.size();
    }
    public static void perm(int start, int r, int n){
        if(start == r){
            // 숫자로 변환
            String str = "";
            for(int i=0; i<select.length; i++)
                str += select[i];
            int num = Integer.parseInt(str);
            // 예외 처리
            if(num == 1 || num == 0)
                return;
            // 소수 인지 검사
            boolean flag = false;
            for(int i=2; i<=Math.sqrt(num); i++){
                if(num % i == 0)
                    flag = true;
            }
            if(!flag)
                set.add(num);
            return;
        }
        for(int i=0; i<n; i++){
            if(!visited[i]){
                visited[i] = true;
                select[start] = chs[i];
                perm(start+1, r, n);
                visited[i] = false;
            }
        }
    }
- 모든 순열을 확인
    
- start를 0부터 증가시키면서 select 배열에 순차적으로 삽입한다.
 - 재귀적으로 perm(start+1, r, n)을 호출한다.
 
 - 구한 문자를 숫자로 바꾸어 소수인지 판단 ==> 해당 숫자의 루트값까지 나누어 확인
 
참고
코드 출처 (정리 굿) 코드 참고 (정말 똑똑하신 분 같음) 소수찾기 순열
회고
숫자 조합을 어떻게 배열에 저장할지 생각해보느라 오래걸렸다. 예전부터 순열 조합이 어려웠는데 극복이 안된다. 그래도 이번 문제로 다시 정리할 수 있어서 좋았다. 다시봐야지