C# 一组集合中的所有可能组合(n选择k)

C# 一组集合中的所有可能组合(n选择k),c#,set,combinatorics,C#,Set,Combinatorics,给定若干集合,例如{1,2,3,4},{1,2},{1},{1,2,3,},…,以及一个数字k,使得应该形成的组合正好是长度k,如果我只能从每个集合中选择一个数字,那么如何生成长度k的唯一组合 有k个集合可供选择。我正在寻找在c#中实现这一点的最有效方法 直觉上,我尝试(尽管我不确定它是否正确)为每个集合生成所有可能的组合,然后将每个集合中的每个i'th组合与后续集合中相应的i'th组合串联起来,形成一个k长的唯一组合,但我确信这类问题有一个普遍的情况 有人能给我一些建议吗?具体来说,这属于哪个

给定若干集合,例如
{1,2,3,4}
{1,2}
{1}
{1,2,3,}
,…,以及一个数字
k
,使得应该形成的组合正好是长度
k
,如果我只能从每个集合中选择一个数字,那么如何生成长度
k
的唯一组合

有k个集合可供选择。我正在寻找在c#中实现这一点的最有效方法

直觉上,我尝试(尽管我不确定它是否正确)为每个集合生成所有可能的组合,然后将每个集合中的每个i'th组合与后续集合中相应的i'th组合串联起来,形成一个
k
长的唯一组合,但我确信这类问题有一个普遍的情况

有人能给我一些建议吗?具体来说,这属于哪个数学或计算机科学主题,以及这些问题通常是如何解决的

在下面的代码段中,数组中的字符串将是例如“31” 这意味着k=2(这些集合中字符串的长度),有两个集合,其中一个是{1,2,3}和{1}。使用这些集合,生成所有唯一的组合并提供计数

private int combicount(string[] theSets)
    {
        int size = theSets[0].Length;
        int count = 0;
        List<HashSet<int>> l = new List<HashSet<int>>();
        foreach (string s in theSets)
        {
            foreach (char c in s)
            {
                HashSet<int> h = new HashSet<int>();
                for (int n = 1; n <= int.Parse(c.ToString()); n++)
                {
                    h.Add(n);
                }
                l.Add(h);
            }

            //toDO - generate all unique combinations by picking exactly 1 from each set in l
            //toDO - count the number of unique combinations generated
        }


        return count;
    }
private int-combicount(字符串[]集合)
{
int size=theset[0]。长度;
整数计数=0;
列表l=新列表();
foreach(这些集中的字符串s)
{
foreach(字符c在s中)
{
HashSet h=新的HashSet();

对于(int n=1;n,您可以使用LINQ像这样求解它:

    private void CombineSets()
    {
        var mySets = new List<HashSet<int>>();
        mySets.Add(new HashSet<int>() { 1, 2, 3, 4 });
        mySets.Add(new HashSet<int>() { 1, 2 });
        mySets.Add(new HashSet<int>() { 1 });
        mySets.Add(new HashSet<int>() { 1, 2, 3 });

        var result = new HashSet<int>();


        while (mySets.Count > 0)
        {
            //get the smallest set
            var set = mySets.OrderBy(x => x.Count).First();
            //remove the set from the collection as we do not need it anymore (we got our value)
            mySets.Remove(set);
            //remove what is in the result from the set (as we only want unique values)
            set.ExceptWith(result);
            //then add the first value from the remaining values to our result set
            result.Add(set.First());

        }
    }
private void组合集()
{
var mySets=新列表();
Add(新的HashSet(){1,2,3,4});
Add(新的HashSet(){1,2});
Add(新的HashSet(){1});
Add(新的HashSet(){1,2,3});
var result=new HashSet();
而(mySets.Count>0)
{
//得到最小的一组
var set=mySets.OrderBy(x=>x.Count).First();
//从集合中删除集合,因为我们不再需要它(我们获得了价值)
mySets.Remove(set);
//从集合中删除结果中的内容(因为我们只需要唯一的值)
设置。除(结果)外;
//然后将剩余值中的第一个值添加到结果集中
result.Add(set.First());
}
}
为了提高效率,您还可以在while循环之前对列表进行排序。这至少解决了问题的前几行


希望这对您有所帮助:)

发布您尝试过的代码。在演示的示例中,集合是有序的,例如:{1,2,3..}。这是真的吗?你是要求一个组合,还是所有可能的枚举?如果你从每个集合中选择一个数字,我不明白你为什么要从每个集合中生成组合。唯一性在这里意味着什么?唯一性肯定与生成多个组合有关?这个问题通常通过首先解决手工计算,然后将手工求解转化为算法,然后实现算法。顺便说一句,你的问题不是“n选择k”。“n选择k”是“给定一组n个元素,选择其中的k个。”你想要“给定k组,从每个元素中选择一个”。参见我在这个问题中的答案。