Get all subset of a set

原创转载请注明出处:http://agilestyle.iteye.com/blog/2360659

找出一个Set集合中的所有子集

比如全集为 {1, 2, 3}

子集则有{},{1},{2},{3},{1,2},{1,3},{2,3},{1,2,3}

此算法的核心思想:递归

package org.fool.java.collections;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

public class GetAllSubSetTest {
    public static void main(String[] args) {
        Set<Integer> set = new HashSet<>();
        set.add(1);
        set.add(2);
        set.add(3);
        set.add(4);

        // set to array
        Integer[] nums = set.toArray(new Integer[set.size()]);
        // use lambda to transform Integer[] to int[]
        printSubSet(Arrays.stream(nums).mapToInt(i -> i).toArray());
    }

    // step 1: decide how many elements in a sub-set to be printed
    public static void printSubSet(int[] nums) {
        for (int i = 0; i <= nums.length; i++) {
            boolean[] ifPrint = new boolean[nums.length];
            printSubSet(nums, ifPrint, 0, i);   // start from 0th index, and the size varies for the loop
        }
    }

    // step 2: Recursively process elements from left to right to print out all possible combination of elements with fixed size
    // we need three additional variables to keep track of status
    // boolean array to know whether printed out or not
    // start is the start index to be printed to prevent duplicates
    // remain is keeping track of how many remaining elements to be processed for the subset action
    public static void printSubSet(int[] nums, boolean[] ifPrint, int start, int remain) {
        // firstly if remain == 0, we done!
        if (remain == 0) {
            System.out.print("{");
            // check each ifPrint status to decide print or not
            for (int i = 0; i < ifPrint.length; i++) {
                if (ifPrint[i]) {
                    System.out.print(nums[i] + ", ");
                }
            }

            System.out.print("}\n");
        } else {
            // we need process char by char from the start position until end
            // before that, we need determine whether we proceed or not to check if (start + remain > nums.length)
            if (start + remain > nums.length) {

            } else {
                for (int i = start; i < nums.length; i++) {
                    // now before we come to recursive part we have to make sure this position is not used
                    if (!ifPrint[i]) {
                        // now assign its value to true as used indicator
                        ifPrint[i] = true;
                        // recursive call
                        printSubSet(nums, ifPrint, i + 1, remain - 1);
                        // set the position back to false and proceed from next element
                        ifPrint[i] = false;
                    }
                }
            }
        }
    }
}

Console Output


 

Reference

https://www.youtube.com/watch?v=wVNV3JEcikA 

猜你喜欢

转载自agilestyle.iteye.com/blog/2360659