
본 글에서는 java에서 조합과 부분집합을 작성하는 다양한 방법을 알아봅니다.
1. 복권 번호를 맞추기 위해 45개 숫자중 6개를 선택했다. - 조합
2. 앨범 정리를 위해 삭제할 사진들을 선택했다. - 부분 집합
반복문 사용 → 반복문이 몇 번 중첩되는지 알며, 그 중첩의 깊이가 깊지 않을 때
재귀 사용 → 반복문의 중첩 깊이가 동적일 때
// 원소를 뽑을 수열
int[] nums = {1, 2, 3, 4, 5, 6, 7};
// nums로부터 5개를 뽑아 조합을 구성할 배열
int[] combination = new int[5];
for (int i = 0; i < nums.length; ++i) {
combination[0] = nums[i];
for (int j = i + 1; j < nums.length; ++j) {
combination[1] = nums[j];
for (int k = j + 1; k < nums.length; ++k) {
combination[2] = nums[k];
for (int l = k + 1; l < nums.length; ++l) {
combination[3] = nums[l];
for (int m = l + 1; m < nums.length; ++m) {
combination[4] = nums[m];
System.out.println(Arrays.toString(combination));
}
}
}
}
}
import java.io.*;
import java.util.*;
class Main {
static List<Integer> input = new ArrayList<>(); // 입력받은 수의 집합
static int n, r;
static int count;
static int[] data; // 조합으로 뽑은 데이터
// index번째 원소를 뽑아 조합을 구성한다.
static void combination(int index, int checked) {
// index가 r에 다다르면 원하는 행위를 한다.
if (index == r) {
count++;
System.out.println("#" + count + " " + Arrays.toString(data));
return;
}
// index번째 원소를 뽑는다.
// 이미 뽑았거나, 뽑지 않기로 결정한 원소들(check 이전 원소들)은 후보에서 제외
for (int i = checked; i < n; ++i) {
data[index] = input.get(i);
combination(index + 1, i + 1);
}
}
public static void main(String[] args) throws Exception {
System.out.println("nCr 출력 프로그램");
// 수열 입력
System.out.print("수열 입력: ");
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
while (st.hasMoreTokens()) {
input.add(Integer.parseInt(st.nextToken()));
}
// r 입력 및 변수 초기화
System.out.print("r 입력: ");
r = Integer.parseInt(br.readLine());
n = input.size();
data = new int[r];
combination(0, 0);
}
}
for (int i = 0; i < n; ++i) {
for (int j = i + 1; j < n; ++j) {
int firstNum = nums[i];
int secondNum = nums[j];
// 원소를 뽑았을 때의 처리
}
}
0개 원소를 뽑은 조합 + 1개 원소를 뽑은 조합 + ... + n개 원소를 뽑은 조합으로 나타낼 수 있습니다.import java.io.*;
import java.util.*;
class Main {
static List<Integer> input = new ArrayList<>(); // 입력받은 수의 집합
static int n, r;
static int count;
static int[] data; // 조합으로 뽑은 데이터
// index번째 원소를 뽑아 조합을 구성한다.
static void combination(int index, int checked) {
// index가 r에 도달하면 하나의 조합이 완성된 것이다.
if (index == r) {
// 하나의 부분집합이 완성되었을 때의 처리
count++;
System.out.println("#" + count + " " + Arrays.toString(data));
return;
}
for (int i = checked; i < n; ++i) {
data[index] = input.get(i);
combination(index + 1, i + 1);
}
}
public static void main(String[] args) throws Exception {
System.out.println("부분집합 출력 프로그램");
// 수열 입력
System.out.print("수열 입력: ");
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
while (st.hasMoreTokens()) {
input.add(Integer.parseInt(st.nextToken()));
}
// 수열로부터 0 ~ n 개의 원소 조합을 선택하는 경우 = 부분집합
n = input.size();
for (int i = 0; i <= n; ++i) {
r = i;
data = new int[r];
combination(0, 0);
}
}
}
import java.io.*;
import java.util.*;
class Main {
static List<Integer> input = new ArrayList<>(); // 입력받은 수의 집합
static int n;
static int count;
static List<Integer> data = new ArrayList<>(); // 부분집합
// index번째 원소를 뽑아 조합을 구성한다.
static void subset(int index) {
// index가 n에 도달하면 하나의 부분집합이 완성된 것
if (index == n) {
// 하나의 부분집합이 완성되었을 때의 처리
count++;
System.out.println("#" + count + " " + data);
return;
}
subset(index + 1);
data.add(input.get(index));
subset(index + 1);
data.remove(data.size() - 1);
}
public static void main(String[] args) throws Exception {
System.out.println("부분집합 출력 프로그램");
// 수열 입력
System.out.print("수열 입력: ");
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
while (st.hasMoreTokens()) {
input.add(Integer.parseInt(st.nextToken()));
}
n = input.size();
// 부분집합 구하기
subset(0);
}
}
int[] nums = {1, 2, 3} 의 모든 부분집합을 구하고 부분집합에 원소가 속해있으면 1, 속하지 않는다면 0을 표시해 보았습니다.

import java.io.*;
import java.util.*;
class Main {
static List<Integer> input = new ArrayList<>(); // 입력받은 수의 집합
static int n;
static int count;
// index번째 원소를 뽑아 조합을 구성한다.
static void subset() {
for (int mask = 0; mask < (1 << n); ++mask) {
List<Integer> temp = new ArrayList<>();
// mask는 각 원소의 포함 여부를 0 또는 1로 나타낸 숫자
for (int j = 0; j < n; ++j) {
if ((mask & 1 << j) != 0)
temp.add(input.get(j));
}
// 하나의 부분집합이 완성되었을 때의 처리
count++;
System.out.println("#" + count + " " + temp);
}
}
public static void main(String[] args) throws Exception {
System.out.println("부분집합 출력 프로그램");
// 수열 입력
System.out.print("수열 입력: ");
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
while (st.hasMoreTokens()) {
input.add(Integer.parseInt(st.nextToken()));
}
n = input.size();
// 부분집합 구하기
subset();
}
}