순열, 조합, 부분집합을 자바로 구현할 때 여러 마음에 들지 않는 부분이 더러 있었다.
1. N, R, ARR등 모든 변수를 static으로 전역변수로 둬야한다
2. is_selected, visited같이 순조부만을 위한 변수도 static으로 전역변수로 두니 다른 변수들하고 용도가 헷갈려짐
3. 순조부의 결과가 보통 재구함수의 기저부분에 완성이 되니, 이때 바로 그 결과를 가지고 로직을 실행하고싶음.(결과값을 모조리 하나의 Array에 넣는건 비효율적)
public class SubSetTest2 {
static int[] arr;
//subSet에 관한 변수도 추가... 여기에 적고 싶지않음..
static boolean[] is_selected;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
arr = Arrays.stream(br.readLine().split(" ")).mapToInt(Integer::parseInt).toArray();
is_selected = new boolean[arr.length];
subSet(0);
}
private static void subSet(int cnt) {
if(cnt == arr.length) {
//subSet결과인 is_selected를 사용한 로직을 다변화하고시싶다.
for (int i = 0; i < is_selected.length; i++) {
System.out.print(((is_selected[i])? arr[i] : "X") + " ");
}
System.out.println();
return;
}
is_selected[cnt] = true;
subSet(cnt+1);
is_selected[cnt] = false;
subSet(cnt+1);
}
}
/* 입력
* 1 2 3
출력
1 2 3
1 2 X
1 X 3
1 X X
X 2 3
X 2 X
X X 3
X X X
*
* */
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
class SubSet{
int[] arr;
boolean[] is_selected;
public SubSet(int[] arr) {
this.arr = arr;
is_selected = new boolean[arr.length];
createSubSet(0);
}
private void createSubSet(int cnt) {
if(cnt == arr.length) {
//순조부 결과인 is_selected를 이용한 로직을 콜백형태로 전달하고 싶어...
for (int i = 0; i < is_selected.length; i++) {
System.out.print(((is_selected[i])? arr[i] : "X") + " ");
}
System.out.println();
return;
}
is_selected[cnt] = true;
createSubSet(cnt+1);
is_selected[cnt] = false;
createSubSet(cnt+1);
}
}
public class SubSetTest {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int[] arr = Arrays.stream(br.readLine().split(" ")).mapToInt(Integer::parseInt).toArray();
new SubSet(arr);
}
}
/* 입력
* 1 2 3
출력
1 2 3
1 2 X
1 X 3
1 X X
X 2 3
X 2 X
X X 3
X X X
*
* */
하지만, 콜백을 넘겨줘서 내가 하고싶은 로직을 순조부의 결과가 나온 곳에서 바로 실행시키고 싶다. 그래서 함수형 인터페이스를 사용하여 고쳤다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
class SubSet{
int[] arr;
boolean[] is_selected;
private BiConsumer<boolean[], SubSet> callback;
public SubSet(int[] arr, BiConsumer<boolean[], SubSet> print) {
this.arr = arr;
is_selected = new boolean[arr.length];
this.callback = print;
createSubSet(0);
}
private void createSubSet(int cnt) {
if(cnt == arr.length) {
//콜백함수를 js처럼 바로 사용하진못하고, 이렇게 .accept()를 활용해야함
this.callback.accept(is_selected, this);
return;
}
is_selected[cnt] = true;
createSubSet(cnt+1);
is_selected[cnt] = false;
createSubSet(cnt+1);
}
}
public class SubSetTest {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int[] arr = Arrays.stream(br.readLine().split(" ")).mapToInt(Integer::parseInt).toArray();
BiConsumer<boolean[], SubSet> print = (is_selected, object)->{
for (int i = 0; i < is_selected.length; i++) {
System.out.print(((is_selected[i])? object.arr[i] : "X") + " ");
}
System.out.println();
};
//콜백함수와 같이 전달
new SubSet(arr, print);
}
}