티스토리 뷰

반응형

알고리즘을 풀다 보면 간혹 조합을 직접 만들어서 사용해야 할 때가 있었는데 그럴 때마다 새로 만들기 귀찮아서 범용 객체를 이번 기회에 만들어봤다.

제네릭을 사용해서 문자열, 숫자(Integer, Double)등 모두 포괄할 수 있도록 설계했다.

 

조합은 getCombination, 중복조합은 getRepeatableCombination 을 호출하면 되고 파라미터 arr은 후보군들을 제네릭 리스트로, r은 그중 몇 개를 뽑을지를 전달한다.

 

결괏값으로는 후보군 중 r개를 뽑아서 만들어진 리스트들을 리스트로 (2중 리스트)로 리턴한다.

public class Combination {
    public static <T> List<List<T>> getCombination(List<T> arr, int r) {
        boolean[] visited = new boolean[arr.size()];
        List<List<T>> result = new ArrayList<>();
        normalCombination(arr, visited, 0, arr.size(), r, result);
        return result;
    }
    private static <T> void normalCombination(List<T> arr, boolean[] visited, int start, int n, int r, List<List<T>> result) {
        if (r == 0) {
            List<T> temp = new ArrayList<>();
            for (int i = 0; i < n; i++) if (visited[i]) temp.add(arr.get(i));
            result.add(temp);
            return;
        }

        for (int i = start; i < n; i++) {
            visited[i] = true;
            normalCombination(arr, visited, i + 1, n, r - 1, result);
            visited[i] = false;
        }
    }

    public static <T> List<List<T>> getRepeatableCombination(List<T> arr, int r) {
        List<List<T>> result = new ArrayList<>();
        repeatableCombination(arr, new Object[r], 0, 0, r, result);
        return result;
    }
    private static <T> void repeatableCombination(List<T> arr, Object[] out, int start, int depth, int r, List<List<T>> result) {
        if (depth == r) {
            List<T> temp = new ArrayList<>();
            for (Object o : out) temp.add((T) o);
            result.add(temp);
            return;
        }
        for (int i = start; i < arr.size(); i++) {
            out[depth] = arr.get(i);
            repeatableCombination(arr, out, i, depth + 1, r, result);
        }
    }
}
반응형
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크