순열


서로 다른 n 개 중 r 개를 골라 순서를 고려해 나열한 경우의 수.

1. swap을 이용한 순열

- 소스코드

import java.util.Arrays;

public class 순열 {
	public static void main(String[] args) {
		perm(new int[] { 1, 2, 3 }, 0);
	}

	static void perm(int[] arr, int idx) {
		if (idx == arr.length) {
			System.out.println(Arrays.toString(arr));
			return;
		}
		for (int i = idx; i < arr.length; i++) {
			swap(arr, idx, i); // 1 2 3 4
			perm(arr, idx + 1); // 1을 두고 2 3 4에 대해서
			swap(arr, idx, i); // 원래대로
		}
	}

	static void swap(int[] arr, int a, int b) {
		int tmp = arr[a];
		arr[a] = arr[b];
		arr[b] = tmp;
	}
}

- 결과

[1, 2, 3]
[1, 3, 2]
[2, 1, 3]
[2, 3, 1]
[3, 2, 1]
[3, 1, 2]

2. 중복을 허용하지 않는 순열

- 소스코드

int[] sel의 크기를 arr.length로 하면 ‘swap을 허용한 순열’의 결과와 똑같다

import java.util.Arrays;

public class 순열 {
	public static void main(String[] args) {
		int[] arr = { 1, 2, 3 };
		perm(arr, new int[2], 0, new boolean[3]);
	}

	public static void perm(int[] arr, int[] sel, int k, boolean[] visited) {
		if (k == sel.length) {
			System.out.println(Arrays.toString(sel));
			return;
		}
		for (int i = 0; i < arr.length; i++) {
			if (!visited[i]) {
				sel[k] = arr[i];
				visited[i] = true;
				perm(arr, sel, k + 1, visited);
				visited[i] = false;
			}
		}
	}
}

- 결과

[1, 2]
[1, 3]
[2, 1]
[2, 3]
[3, 1]
[3, 2]

3. 중복을 허용한 순열

- 소스코드

import java.util.Arrays;

public class 순열 {
	public static void main(String[] args) {
		int[] arr = { 1, 2, 3 };
		perm(arr, new int[2], 0);
	}

	
	public static void perm(int[] arr, int[] sel, int cnt) {
		if (sel.length == cnt) {
			System.out.println(Arrays.toString(sel));
			return;
		}

		for (int i = 0; i < arr.length; i++) {
			sel[cnt] = arr[i];
			perm(arr, sel, cnt + 1);
		}
	}
}

- 결과

[1, 1]
[1, 2]
[1, 3]
[2, 1]
[2, 2]
[2, 3]
[3, 1]
[3, 2]
[3, 3]