완전 탐색
무식해보여도 사실은 최고의 방법일때가 있지요
완전 탐색 알고리즘은 나올 수 있는 모든 경우의 수를 다 구해서 올바른 정답을 구하는 알고리즘 입니다.
완전 탐색을 구현하는 방법은 여러가지가 있지만
이 글에서는 재귀호출로 완전탐색 알고리즘을 구현해보도록 하겠습니다.
소수 찾기
출처: 프로그래머스 코딩 테스트 연습, https://programmers.co.kr/learn/challenges
한자리 숫자가 적힌 종이 조각이 흩어져있습니다. 흩어진 종이 조각을 붙여 소수를 몇 개 만들 수 있는지 알아내려 합니다. 각 종이 조각에 적힌 숫자가 적힌 문자열 numbers가 주어졌을 때, 종이 조각으로 만들 수 있는 소수가 몇 개인지 return 하도록 solution 함수를 완성해주세요.
제한 상황
- numbers는 길이 1 이상 7 이하인 문자열입니다.
- numbers는 0~9까지 숫자만으로 이루어져 있습니다.
- 013은 0, 1, 3 숫자가 적힌 종이 조각이 흩어져있다는 의미입니다.
입출력 예)
numbers | return |
17 | 3 |
011 | 2 |
입력 numbers의 값이 "17"일때 나올 수 있는 경우의 수는 총 4가지이고 소수일 경우는 3가지 입니다..
경우의 수 | 소수 |
1 | X |
17 | O |
7 | O |
71 | O |
이처럼 나올 수 있는 모든 경우의 수를 다 구하고 판별해야 하는 것이 완전 탐색입니다.
구현
모든 경우의 수 구하기
소수를 찾기 전에 해야할 일은 입력된 numbers 값으로 나올 수 있는 모든 경우의 수를 구하는 것입니다. 중복이 포함되면 안되구요. 두번째 입출력 "011" 처럼 같은 숫자가 존재하는 경우, 서로 다른 인덱스를 접근해서 만든 조합의 값이 중복될 가능성이 있어 주의 해야합니다.
따라서 중복 값이 포함되지 않는 Set 자료구조이 HashSet 클래스를 사용합니다.
import java.util.*;
public int solution(String numbers)
{
HashSet<Integer> set = new HashSet<>();
int answer = 0;
permutation("",numbers,set);
// 소수 구하기 생략
return answer;
}
// prefix 조합으로 만들어진 경우의 수
// numbers 조합으로 만들 수 있는 숫자 모음
public void permutation(String prefix,String numbers,HashSet<Integer> set)
{
int n = numbers.length();
if(!prefix.equals("")) set.add(Integer.valueOf(prefix));
for(int i = 0;i<n;i++)
{
permutation(prefix + numbers.chatAt(i),
numbers.substring(0,i)+numbers.substring(i+1),
set);
}
}
위 함수의 흐름 이해하셨나요? 처음 호출 될 시 prefix의 값이 "" 인경우를 제외하고, 나머지 함수 호출 부분의 Prefix의 값들은 모두 HashSet 객체에 들어가게 됩니다. 혹시나 코드의 흐름이 이해가 가지 않는 다면 댓글을 남겨주시길 바랍니다.
이후 소수 찾기 로직은 다른 포스팅에서 소개하겠습니다.
'Algorithm_Java' 카테고리의 다른 글
[알고리즘] 백준 12865 - 평범한 배낭 (0) | 2020.07.16 |
---|---|
[알고리즘] 백준 2565 - 전깃줄 (0) | 2020.07.12 |
[알고리즘] 백준 2580 - 스도쿠 (0) | 2020.06.22 |
[알고리즘] 백준 11729 - 하노이 탑 이동 순서 (0) | 2020.06.05 |
[알고리즘] 백준 1929 소수 구하기 - 에라토스테네스의 체 (0) | 2020.06.02 |