是否有一种方法会为n选择k返回所有可能的组合?

时间:2019-01-17 18:50:06

标签: java math combinations

我正在寻找库函数,该函数返回k个集合中n个子集的任意组合。例如,我有一个{1,2,3,4,5}集合,并且需要此集合中包含的3个数字的任意组合。顺序无关紧要。 因此,此函数应返回:

  

[[1、2、3],[1、2、4],[1、2、5],[1、3、4],[1、3、5],[1、4、5 ],[2,   3,4],[2、3、5],[2、4、5],[3、4、5]]

我试图自己写它,但是没有成功,我放弃了。仅当我从任意集合中提取3个数字时,此方法才有效。 也许有人知道此问题的库功能。

3 个答案:

答案 0 :(得分:0)

我不了解任何库函数,但是您可以使用以下解决方案:

df['year'] = df.index.year
df['weekofyear'] = df.index.weekofyear
df['Weekly_Cum'] = df.groupby(['year', 'weekofyear']).cumsum()

它基于amit's solution

答案 1 :(得分:0)

这是使用流的简单且简短的解决方案:

import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Set;

import static java.util.stream.Collectors.toSet;

public class MakeSubsets {
  static <T> Set<Set<T>> subsets(Set<T> set, int size) {
    if (size < 1) {
      return Collections.singleton(Collections.emptySet());
    }
    return set.stream()
          .flatMap(e -> subsets(remove(set, e), size - 1).stream().map(s -> add(s, e)))
          .collect(toSet());
  }

  static <T> Set<T> add(Set<T> set, T elem) {
    Set<T> newSet = new LinkedHashSet<>(set);
    newSet.add(elem);
    return newSet;
  }

  static <T> Set<T> remove(Set<T> set, T elem) {
    Set<T> newSet = new LinkedHashSet<>(set);
    newSet.remove(elem);
    return newSet;
  }

  public static void main(String[] args) {
    Set<Integer> set = new LinkedHashSet<>(Arrays.asList(1, 2, 3, 4, 5));
    System.out.println(subsets(set, 3));
  }
}

工作原理:方法subsets产生给定大小的所有子集的集合。

对于size < 1,它返回一个集合,其中仅包含空集合。

否则,对于给定集合的每个元素,它将生成一个没有此选定元素的新集合。然后,它(递归地)生成具有此较小集合的size - 1个元素的子集。然后将所选元素添加到结果中的每个集合中。因此,结果中的所有集合都具有所需的大小。

递归终止,因为在每个递归级别中,size将减少一个,平均为< 1

这里的假设是set.size() >= sizesize >= 0

答案 2 :(得分:0)

我在这里找到了递归解决方案: https://stackoverflow.com/a/16256122/10929764 但它只会打印出组合。我试图对其进行修改,以将所有组合作为ArrayList返回,但是它不起作用。 这是代码:

public ArrayList<String[]> comb2(ArrayList<String>arr, int len, int startPosition, String[] result, ArrayList<String[]> allResults){
    if (len == 0){
        System.out.println(Arrays.toString(result));
        allResults.add(result);
        return allResults;
    }
    for (int i = startPosition; i <= arr.size()-len; i++){
        result[result.length - len] = arr.get(i);
        comb2(arr, len-1, i+1, result,allResults);
    }
    return allResults;
}

它会正确打印所有组合:

  

[A,B,C] [A,B,D] [A,B,E] [A,C,D] [A,C,E] [A,D,E] [B,C, D]   [B,C,E] [B,D,E] [C,D,E]

但是当我打印出之前由comb2方法返回的allResults时,我得到了:

  

[C,D,E] [C,D,E] [C,D,E] [C,D,E] [C,D,E] [C,D,E] [C,D, E]   [C,D,E] [C,D,E] [C,D,E]