08
12
728x90

직관적으로 예시를 드는것이 이해하기 쉬워서 주사위 던지는 것을 예시로 든다.


중복 순열

- 주사위 3개를 던져 나올 수 있는 모든 경우의 수

- 123, 231은 다른 경우로 본다. 즉, 뽑는 순서가 상관이 있다.

- 112처럼 같은 수를 중복으로 뽑을 수 있다.

- n개 중 r개를 뽑는 모든 경우의 수를 nπr로 표현한다.

코드

결과

111, 112, 113, ~, 211, 212, ~ 666


순열

- 주사위 3개를 던져 모두 다른 수가 나올 수 있는 경우의 수

- 123, 231은 다른 경우로 본다. 즉, 뽑는 순서가 상관이 있다.

- 112처럼 같은 수를 중복으로 뽑을 수 없다.

- n개 중 r개를 중복되지 않게 뽑는 모든 경우의 수를 nPr로 표현한다.

코드

결과

123, 124, 125, ~, 213, 214, ~, 654


중복 조합

- 주사위 3개를 던져 나올 수 있는 경우의 수로, 순서를 따지지 않는다.

- 123, 231은 같은 경우로 본다. 즉, 뽑는 순서가 상관이 없다.

- 112처럼 같은 수를 중복으로 뽑을 수 있다.

- n개 중 r개를 순서를 따지지 않고 뽑는 모든 경우의 수를 nHr로 표현한다.

코드

결과

111, 112, 113, ~, 222, 223, ~, 666


조합

- 주사위 3개를 던져 모두 다른 수가 나올 수 있는 경우의 수로, 순서를 따지지 않는다.

- 123, 231은 같은 경우로 본다. 즉, 뽑는 순서가 상관이 없다.

- 112처럼 같은 수를 중복으로 뽑을 수 없다.

- n개 중 r개를 순서를 따지지 않고 중복되지 않게 뽑는 모든 경우의 수를 nCr로 표현한다.

코드

결과

123, 124, ~, 234, 235, ~, 456


전체코드

더보기
import java.util.Arrays;
import java.util.Scanner;

public class DiceTest {

	static int N, numbers[];
	static boolean[] isSelected;

	public static void main(String[] args) {

		// 입력으로 주사위 던지는 횟수, 주사위 던지기 모드(1, 2, 3, 4)
		Scanner sc = new Scanner(System.in);
		N = sc.nextInt(); // 주사위 던지는 횟수(0 < N < 7)
		int M = sc.nextInt(); // 주사위 던지기 모드
		numbers = new int[N]; // 던져진 주사위 수들
		switch (M) {
		case 1: // 중복순열
			dice1(0);
			break;
		case 2: // 순열
			isSelected = new boolean[7]; // 주사위 0번 사용x
			dice2(0);
			break;
		case 3: // 중복조합
			dice3(0, 1);
			break;
		case 4: // 조합 6C2 = 6! / 2! * 4! = 15가지
			dice4(0, 1);
			break;
		}
		sc.close();
	}

	// 중복 순열
	static void dice1(int cnt) { // cnt + 1번째 주사위 던지기, cnt: 기존까지 던져진 주사위 횟수

		if (cnt == N) { // N번을 다 던진 경우
			System.out.println(Arrays.toString(numbers));
			return;
		}

		// 한 번 던질 때 가능한 상황에 대한 시도(1, 2, 3, 4, 5, 6 주사위 눈이 가능)
		for (int i = 1; i <= 6; i++) {
			numbers[cnt] = i;
			// 현 주사위의 눈이 i로 결정된 상태로 다음 주사위 던지러 가기
			dice1(cnt + 1);
		}
	}

	// 순열
	static void dice2(int cnt) { // cnt + 1번째 주사위 던지기, cnt: 기존까지 던져진 주사위 횟수

		if (cnt == N) { // N번을 다 던진 경우
			System.out.println(Arrays.toString(numbers));
			return;
		}

		// 한 번 던질 때 가능한 상황에 대한 시도(1, 2, 3, 4, 5, 6 주사위 눈이 가능)
		for (int i = 1; i <= 6; i++) {
			// 기존 주사위의 눈과 중복되는지 체크
			if (isSelected[i])
				continue;
			numbers[cnt] = i;
			isSelected[i] = true;
			// 현 주사위의 눈이 i로 결정된 상태로 다음 주사위 던지러 가기
			dice2(cnt + 1);
			// 현 주사위의 눈을 다른 선택지로 시도하기 위한 준비
			isSelected[i] = false;
		}
	}

	// 중복조합
	static void dice3(int cnt, int start) { // start: 시작 주사위 눈의 수

		if (cnt == N) {
			System.out.println(Arrays.toString(numbers));
			return;
		}

		for (int i = start; i <= 6; i++) {
			numbers[cnt] = i;
			dice3(cnt + 1, i); // i: 뽑는 수
		}
	}

	// 조합
	static void dice4(int cnt, int start) { // start: 시작 주사위 눈의 수

		if (cnt == N) {
			System.out.println(Arrays.toString(numbers));
			return;
		}

		for (int i = start; i <= 6; i++) {
			numbers[cnt] = i;
			dice4(cnt + 1, i + 1);
		}
	}
}
728x90

'개발 > 알고리즘' 카테고리의 다른 글

부분집합(Subset)  (0) 2023.08.12
조합(Combination)  (0) 2023.08.12
순열(Permutation)  (0) 2023.08.12
완전 검색, 완전 탐색(Exhaustive Search)  (0) 2023.08.12
COMMENT