서로 다른 n개의 원소 중 r 개를 순서 있게 고르는 것
// 순열
static void perm(int cnt) {
if(cnt == m) {
for(int temp : ret) {
System.out.print(temp+" ");
}
System.out.println();
return;
}
for(int i = 0; i < n; i++) {
if(!visited[i]) {
ret[cnt] = num[i];
visited[i] = true;
perm(cnt +1);
visited[i] = false;
}
}
}
visited 배열을 사용하여 방문 체크를 해줘야 한다.
함수가 끝나면 방문 배열을 복구 해줘야 한다
중복이 가능한 수열
//중복순열
static void perm2(int cnt) {
if(cnt == m) {
for(int temp : ret) {
System.out.print(temp+" ");
}
System.out.println();
return;
}
for(int i = 0; i < n; i++) {
ret[cnt] = num[i];
perm(cnt +1);
}
}
중복이 가능하기 때문에 visited 배열을 사용할 필요가 없다.
n개의 수에서 r 개를 고르는 것 (1,2) (2,1)이 동일하다.
//조합
static void combi(int cnt, int start) {
if(cnt == m) {
for(int temp : ret) {
System.out.print(temp+" ");
}
System.out.println();
return;
}
for(int i = start; i < n; i++) {
ret[cnt] = num[i];
combi(cnt + 1, i + 1);
}
}
//중복조합
static void combi2(int cnt, int start) {
if(cnt == m) {
for(int temp : ret) {
System.out.print(temp+" ");
}
System.out.println();
return;
}
for(int i = start; i < n; i++) {
ret[cnt] = num[i];
combi(cnt +1, i);
}
}
static void subset(int cnt) {
if(cnt == n) {
for(int i = 0; i < n; i++) {
if(visited[i]) {
System.out.print(num[i]+" ");
}
}
System.out.println();
return;
}
//선택했거나 안 했거나
visited[cnt] = true;
subset(cnt + 1);
visited[cnt] = false;
subset(cnt + 1);
}
static void subset2(int cnt, int select) {
if(cnt == n) {
if(select >= 1) {
for(int i = 0; i < n; i++) {
if(visited[i]) {
System.out.print(num[i]+" ");
}
}
System.out.println();
}
return;
}
visited[cnt] = true;
subset2(cnt + 1, select +1);
visited[cnt] = false;
subset2(cnt + 1, select);
}
몇개 선택 되었는지 매개변수로 넘겨주면서 체크한다.
하나도 선택 안 된 경우는 공집합이니까 출력 X