Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 唯一组合算法_Algorithm_Combinations - Fatal编程技术网

Algorithm 唯一组合算法

Algorithm 唯一组合算法,algorithm,combinations,Algorithm,Combinations,我一直在试图找到一种方法,从嵌套在容器中的对象列表中获取唯一组合的列表。不能合并同一组中的对象。对象在所有组中都是唯一的 例如: Group 1: (1,2) Group 2: (3,4) 结果 1 2 3 4 1,3 1,4 2,3 2,4 如果我们添加另一个类似的组: Group 1: (1,2) Group 2: (3,4) Group 3: (5,6,7) 结果将是 1 2 3 4 5 6 7 1,3 1,4 1,5 1,6 1,7 2,3 2,4 2,5 2,6 2,7 3,5

我一直在试图找到一种方法,从嵌套在容器中的对象列表中获取唯一组合的列表。不能合并同一组中的对象。对象在所有组中都是唯一的

例如:

Group 1: (1,2)
Group 2: (3,4)
结果

1
2
3
4
1,3
1,4
2,3
2,4
如果我们添加另一个类似的组:

Group 1: (1,2)
Group 2: (3,4)
Group 3: (5,6,7)
结果将是

1
2
3
4
5
6
7
1,3
1,4
1,5
1,6
1,7
2,3
2,4
2,5
2,6
2,7
3,5
3,6
3,7
4,5
4,6
4,7
1,3,5
1,3,6
1,3,7
1,4,5
1,4,6
1,4,7
2,3,5
2,3,6
2,3,7
2,4,5
2,4,6
2,4,7
我可能错过了上面的一个组合,但上面提到的组合应该足以说明问题

我有可能有7组,每个对象20组

我试图避免让代码知道它是在做双倍、三倍、四倍等的组合,但在这过程中我遇到了很多逻辑障碍

明确地说,我不是在要求代码,更多的是一种方法,伪代码或指示将非常有用

更新 这是我看到这两个答案后得到的

来自@Servy的回答:

public static IEnumerable<IEnumerable<T>> GetCombinations<T>(this IEnumerable<IEnumerable<T>> sequences)
    {
        var defaultArray = new[] { default(T) };

        return sequences.Select(sequence =>
                sequence.Select(item => item).Concat(defaultArray))
            .CartesianProduct()
            .Select(sequence =>
                sequence.Where(item => !item.Equals(default(T)))
                .Select(item => item));
    }

    public static IEnumerable<IEnumerable<T>> CartesianProduct<T>(this IEnumerable<IEnumerable<T>> sequences)
    {
        IEnumerable<IEnumerable<T>> emptyProduct = new[] { Enumerable.Empty<T>() };
        return sequences.Aggregate(
            emptyProduct,
            (accumulator, sequence) =>
                from accseq in accumulator
                from item in sequence
                select accseq.Concat(new[] { item })
            );
    }
公共静态IEnumerable GetCombinations(此IEnumerable序列)
{
var defaultArray=new[]{default(T)};
返回序列。选择(序列=>
sequence.Select(item=>item.Concat(defaultArray))
.CartesianProduct()
.选择(序列=>
sequence.Where(item=>!item.Equals(默认值(T)))
.选择(项目=>项目));
}
公共静态IEnumerable CartesianProduct(此IEnumerable序列)
{
IEnumerable emptyProduct=new[]{Enumerable.Empty()};
返回序列.聚合(
空产品,
(累加器,顺序)=>
来自蓄能器中的accseq
按顺序从项目开始
选择accseq.Concat(新[]{item})
);
}
来自@AK_uz的回答

public static IEnumerable<IEnumerable<T>> GetCombinations<T>(this IEnumerable<IEnumerable<T>> groups)
    {

        if (groups.Count() == 0)
        {
            yield return new T[0];
        }

        if (groups.Count() == 1)
        {
            foreach (var t in groups.First())
            {
                yield return new T[] { t };
            }
        }

        else
        {
            var furtherResult = GetCombinations(groups.Where(x => x != groups.Last()));

            foreach (var result in furtherResult)
            {
                yield return result;
            }

            foreach (var t in groups.Last())
            {
                yield return new T[] { t };

                foreach (var result in furtherResult)
                {
                    yield return result.Concat(new T[] { t });
                }
            }
        }
    }
公共静态IEnumerable GetCombinations(此IEnumerable组)
{
如果(groups.Count()==0)
{
收益率-收益率新T[0];
}
if(groups.Count()==1)
{
foreach(组中的var t.First())
{
产生返回新的T[]{T};
}
}
其他的
{
var-furtherResult=getcombines(groups.Where(x=>x!=groups.Last());
foreach(进一步结果中的var结果)
{
收益结果;
}
foreach(组中的var t.Last())
{
产生返回新的T[]{T};
foreach(进一步结果中的var结果)
{
产生返回结果.Concat(新的T[]{T});
}
}
}
}
两者的用法

List<List<int>> groups = new List<List<int>>();

        groups.Add(new List<int>() { 1, 2 });
        groups.Add(new List<int>() { 3, 4, 5 });
        groups.Add(new List<int>() { 6, 7 });
        groups.Add(new List<int>() { 8, 9 });
        groups.Add(new List<int>() { 10, 11 });


        var x = groups.GetCombinations().Where(g => g.Count() > 0).ToList().OrderBy(y => y.Count());
列表组=新列表();
添加(新列表(){1,2});
添加(新列表(){3,4,5});
添加(新列表(){6,7});
添加(新列表(){8,9});
添加(新列表(){10,11});
var x=groups.getcombines().Where(g=>g.Count()>0.ToList().OrderBy(y=>y.Count());

什么是最佳解决方案?老实说,我能够阅读AKY的解决方案所发生的事情要容易得多(必须寻找一个如何得到笛卡尔积的解决方案)。也就是说,每个序列中一个值的每个组合

但是我们如何处理输出组合的大小小于序列数的情况呢?它只处理给定序列的大小与序列数相同的情况。好吧,想象一下,每一个输入序列都有一个“空”值。该空值与来自其他序列(包括其所有空值)的每个值组合成对。然后我们可以在最后删除这些空值,瞧,我们有各种大小的组合

为此,在仍然允许输入序列实际使用C#literal
null
值或该类型的默认值(如果不可为null)的同时,我们需要包装该类型。我们将创建一个包装器来包装实际值,同时也有自己的def-ult/null值定义。从那里,我们将每个序列映射到一个包装器序列中,将实际默认值附加到末尾,计算笛卡尔积,然后将组合映射回“真实”值,在处理时过滤掉默认值

如果您不想看到实际的代码,请停止阅读此处


公共类包装器
{
公共包装器(T值){value=value;}
公共静态包装默认值=新包装(默认值(T));
公共T值{get;私有集;}
}
公共静态IEnumerable Foo
(这是不可数序列)
{
返回序列。选择(序列=>
sequence.Select(item=>newwrapper(item))
.Concat(新[]{Wrapper.Default}))
.CartesianProduct()
.选择(序列=>
sequence.Where(wrapper=>wrapper!=wrapper.Default)
.Select(wrapper=>wrapper.Value));
}
在C语言中#

这实际上是一个单子。。。我想

IEnumerable<IEnumerable<int>> foo (IEnumerable<IEnumerable<int>> groups)
{

    if (groups.Count == 0)
    {
        return new List<List<int>>();
    }

    if (groups.Count == 1)
    {
        foreach(van num in groups.First())
        {
            return yield new List<int>(){num};
        }
    }

    else
    {
        var furtherResult = foo(groups.Where(x=> x != groups.First()));

        foreach (var result in furtherResult)
        {
            yield  return result;
        }

        foreach(van num in groups.First())
        {
            yield return new List<int>(){num};

            foreach (var result in furtherResult)
            {
                yield return result.Concat(num);
            }
        }
    }
}
IEnumerable foo(IEnumerable组)
{
如果(groups.Count==0)
{
返回新列表();
}
如果(groups.Count==1)
{
foreach(组中的van num.First())
{
返回yield new List(){num};
}
}
其他的
{
var-furtherResult=foo(groups.Where(x=>x!=groups.First());
foreach(进一步结果中的var结果)
{
收益结果;
}
foreach(组中的van num.First())
{
返回新列表(){num};
foreach(进一步结果中的var结果)
{
收益率返回结果。Concat(num);
}
}
}
}

更好的版本:

public static IEnumerable<IEnumerable<T>> foo<T> (IEnumerable<IEnumerable<T>> groups)
    {
        if (groups.Count() == 0)
        {
            return new List<List<T>>();
        }

        else
        {
            var firstGroup = groups.First();

            var furtherResult = foo(groups.Skip(1));

            IEnumerable<IEnumerable<T>> myResult =  from x in firstGroup
                select new [] {x};

            myResult = myResult.Concat(  from x      in firstGroup 
                                       from result in furtherResult
                                       select result.Concat(new T[]{x}));

            myResult = myResult.Concat(furtherResult);

            return myResult;
        }
    }
公共静态IEnumerable foo(IEnumerabl
IEnumerable<IEnumerable<int>> foo (IEnumerable<IEnumerable<int>> groups)
{

    if (groups.Count == 0)
    {
        return new List<List<int>>();
    }

    if (groups.Count == 1)
    {
        foreach(van num in groups.First())
        {
            return yield new List<int>(){num};
        }
    }

    else
    {
        var furtherResult = foo(groups.Where(x=> x != groups.First()));

        foreach (var result in furtherResult)
        {
            yield  return result;
        }

        foreach(van num in groups.First())
        {
            yield return new List<int>(){num};

            foreach (var result in furtherResult)
            {
                yield return result.Concat(num);
            }
        }
    }
}
public static IEnumerable<IEnumerable<T>> foo<T> (IEnumerable<IEnumerable<T>> groups)
    {
        if (groups.Count() == 0)
        {
            return new List<List<T>>();
        }

        else
        {
            var firstGroup = groups.First();

            var furtherResult = foo(groups.Skip(1));

            IEnumerable<IEnumerable<T>> myResult =  from x in firstGroup
                select new [] {x};

            myResult = myResult.Concat(  from x      in firstGroup 
                                       from result in furtherResult
                                       select result.Concat(new T[]{x}));

            myResult = myResult.Concat(furtherResult);

            return myResult;
        }
    }