Find all subsets of length k in an array

前端 未结 13 1689
梦谈多话
梦谈多话 2020-11-27 05:34

Given a set {1,2,3,4,5...n} of n elements, we need to find all subsets of length k .

For example, if n = 4 and k = 2, the output would be

相关标签:
13条回答
  • 2020-11-27 05:51

    This is an implemation in F#:

    // allSubsets: int -> int -> Set<Set<int>>
    let rec allSubsets n k =
        match n, k with
        | _, 0 -> Set.empty.Add(Set.empty)
        | 0, _ -> Set.empty
        | n, k -> Set.union (Set.map (fun s -> Set.add n s) (allSubsets (n-1) (k-1)))
                            (allSubsets (n-1) k)
    

    You can try it in the F# REPL:

    > allSubsets 3 2;;
    
    val it : Set<Set<int>> = set [set [1; 2]; set [1; 3]; set [2; 3]]
    
    > allSubsets 4 2;;
    
    val it : Set<Set<int>> = set [set [1; 2]; set [1; 3]; set [1; 4]; set [2; 3]; set [2; 4]; set [3; 4]]
    

    This Java class implements the same algorithm:

    import java.util.HashSet;
    import java.util.Set;
    
    public class AllSubsets {
    
        public static Set<Set<Integer>> allSubsets(int setSize, int subsetSize) {
            if (subsetSize == 0) {
                HashSet<Set<Integer>> result = new HashSet<>();
                result.add(new HashSet<>());
                return result;
            }
            if (setSize == 0) {
                return new HashSet<>();
            }
            Set<Set<Integer>> sets1 = allSubsets((setSize - 1), (subsetSize - 1));
            for (Set<Integer> set : sets1) {
                set.add(setSize);
            }
            Set<Set<Integer>> sets2 = allSubsets((setSize - 1), subsetSize);
            sets1.addAll(sets2);
            return sets1;
        }
    }
    

    If you do not like F# or Java then visit this website. It lists solutions to your particular problem in various programming languages:

    http://rosettacode.org/wiki/Combinations

    0 讨论(0)
  • 2020-11-27 05:51

    JavaScript implementation:

    var subsetArray = (function() {
      return {
        getResult: getResult
      }
    
      function getResult(array, n) {
    
        function isBigEnough(value) {
          return value.length === n;
        }
    
        var ps = [
          []
        ];
        for (var i = 0; i < array.length; i++) {
          for (var j = 0, len = ps.length; j < len; j++) {
            ps.push(ps[j].concat(array[i]));
          }
        }
        return ps.filter(isBigEnough);
      }
    })();
    
    
    
     var arr = [1, 2, 3, 4,5,6,7,8,9];
     console.log(subsetArray.getResult(arr,2));
    
    0 讨论(0)
  • 2020-11-27 05:52

    Here is a Java version of what I think Simple is talking about, using a binary representation of all sets in the power set. It's similar to how Abhiroop Sarkar did it, but I think a boolean array makes more sense than a string when you are just representing binary values.

    private ArrayList<ArrayList<Object>> getSubsets(int m, Object[] objects){
        // m = size of subset, objects = superset of objects
        ArrayList<ArrayList<Object>> subsets = new ArrayList<>();
        ArrayList<Integer> pot = new ArrayList<>();
        int n = objects.length;
        int p = 1;
        if(m==0)
            return subsets;
        for(int i=0; i<=n; i++){
            pot.add(p);
            p*=2;
        }
        for(int i=1; i<p; i++){
            boolean[] binArray = new boolean[n];
            Arrays.fill(binArray, false);
            int y = i;
            int sum = 0;
            for(int j = n-1; j>=0; j--){
                int currentPot = pot.get(j);
                if(y >= currentPot){
                    binArray[j] = true;
                    y -= currentPot;
                    sum++;
                }
                if(y<=0)
                    break;
            }
            if(sum==m){
                ArrayList<Object> subsubset = new ArrayList<>();
                for(int j=0; j < n; j++){
                    if(binArray[j]){
                        subsubset.add(objects[j]);
                    }
                }
                subsets.add(subsubset);
            }
        }
    
        return subsets;
    }
    
    0 讨论(0)
  • 2020-11-27 05:57

    Use a bit vector representation of the set, and use an algorithm similar to what std::next_permutation does on 0000.1111 (n-k zeroes, k ones). Each permutation corresponds to a subset of size k.

    0 讨论(0)
  • 2020-11-27 06:00

    This is python. Sorry for the spanish ;)

    from pprint import pprint
    conjunto = [1,2,3,4, 5,6,7,8,9,10]
    k = 3
    lista = []
    iteraciones = [0]
    def subconjuntos(l, k):
        if k == len(l):
            if not l in lista:
                lista.append(l)
            return
        for i in l:
            aux = l[:]
            aux.remove(i)
            result = subconjuntos(aux, k)
            iteraciones[0] += 1
            if not result in lista and result:
                lista.append( result)
    
    subconjuntos(conjunto, k)
    print (lista)
    print ('cant iteraciones: ' + str(iteraciones[0]))
    
    0 讨论(0)
  • 2020-11-27 06:01

    Please check my solution:-

    private static void printPermutations(List<Integer> list, int subSetSize) {
        List<Integer> prefixList = new ArrayList<Integer>();
        printPermutations(prefixList, list, subSetSize);
    }
    
    private static void printPermutations(List<Integer> prefixList, List<Integer> list, int subSetSize) {
        if (prefixList.size() == subSetSize) {
            System.out.println(prefixList);
        } else {
            for (int i = 0; i < list.size(); i++) {
                Integer removed = list.remove(i);
                prefixList.add(removed);
                printPermutations(prefixList, list, subSetSize);
                prefixList.remove(removed);
                list.add(i, removed);
            }
        }
    }
    

    This is similar to String permutations:-

    private static void printPermutations(String str) {
        printAllPermutations("", str);
    }
    
    private static void printAllPermutations(String prefix, String restOfTheString) {
        int len = restOfTheString.length();
        System.out.println(prefix);
        for (int i = 0; i < len; i++) {
            printAllPermutations(prefix + restOfTheString.charAt(i), restOfTheString.substring(0, i) + restOfTheString.substring(i + 1, len));
        }
    }
    
    0 讨论(0)
提交回复
热议问题