코드: https://github.com/kgh128/Problem-Solving/blob/main/src/Baekjoon/p6603.java
재귀함수를 이용하여 가능한 로또 조합을 만든다. 먼저 조합 배열 combination의 count번째 원소에 현재 방문한 S의 원소를 넣는다. 이때 count의 값도 1 증가시킨다. count 변수는 0~5 범위의 수로, 현재 로또(6자리)의 몇번째 수를 넣고 있는지를 의미한다.
만약 count 값이 5를 넘어가면 6자리를 다 채웠다는 의미이므로, 출력 버퍼에 combination 배열에 있는 로또 조합을 저장하고, return한다. return 되면 이전 호출의 for문으로 돌아갈텐데(아래 문단 참고), 그럼 for문이 돌아서 다음 원소를 로또의 다음 자리에 넣어봤을 때의 조합을 다시 재귀호출을 통해 만들어본다.
만약 count 값이 5를 넘어가지 않는다면 아직 채워야 할 자리가 존재하므로, 로또의 다음 자리에 S 배열에서 다음 원소 ~ 마지막 원소를 넣었을 때의 조합을 만들어본다. 이는 for문을 돌면서 current 값을 다음 인덱스 ~ 마지막 인덱스로 넣고 makeCombination 함수를 재귀 호출하는 형식으로 구현한다.
public static void makeCombination(int current, int count, int[] combination) {
combination[count++] = S[current];
if (count > 5) {
for (int i = 0; i < 6; i++) {
sb.append(combination[i]).append(' ');
}
sb.append('\n');
return;
}
for (int i = current+1; i < K; i++) {
makeCombination(i, count, combination);
}
}
처음에는 로또 조합 배열을
int배열을 사용하지 않고, 바로StringBuilder를 사용하였다. 그런데,StringBuilder객체에append()메소드를 사용한 결과는 리턴되어도 남아있다는 문제가 있었다. 원래 의도했던 것은StringBuilder에 5를 넣어서 "1 2 3 4 6 5"의 조합이 만들어지고, 리턴되면 이전 호출에서는 "1 2 3 4 6"만 남아있는 것이었다. 하지만 그대로 "1 2 3 4 6 5"가 남고, 그 이후를 진행하면 여기에 덧붙여져서 "1 2 3 4 6 5 7" 이렇게 잘못된 로또 조합이 나왔다. 그리하여int배열을 사용하였다.
int배열도StringBuilder도 객체의 주소가 전달되어 변경 사항이 그대로 적용된다는 것은 동일하지만,int배열은 원소를 계속 추가하는 것이 아니라, 인덱스를 통해 접근하여 원소의 값을 직접 바꿀 수 있어서 원하는 결과가 나왔다. 물론StringBuilder도 가능하기는 하지만, 이는 모든 것을 다 문자열 취급하므로int배열처럼 숫자 하나를 다른 숫자로 바꾸는 게 용이하지 않았다. 예를 들어 123이 있을 경우int배열에서는 하나의 원소로 취급하지만,StringBuilder는 3개의 원소로 취급하기 때문에 숫자 하나를 지우는 것이 더 까다로웠다. (숫자의 길이에 따라 인덱스가 달라짐.)
makeCombination 함수를 이용하여 가능한 로또 조합을 만들었다. main 함수 내에서도 for문을 돌며 순차적으로 S의 원소를 로또의 첫번째 자리로 주고 makeCombination 함수를 호출하였다.
예를 들어, i가 0일 때는 S의 0번째 원소로 시작하는 모든 로또 조합을 구하고, i가 1일 때는 1번째 원소로 시작하는 모든 로또 조합을 구하는 형식이다.
for (int i = 0; i < K; i++) {
makeCombination(i, 0, new int[6]);
}
sb.append('\n');