Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/317.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
C# 为字符串列表生成所有组合_C#_Math_Combinations - Fatal编程技术网

C# 为字符串列表生成所有组合

C# 为字符串列表生成所有组合,c#,math,combinations,C#,Math,Combinations,我想生成一个字符串列表的所有可能组合的列表(实际上是一个对象列表,但为了简单起见,我们将使用字符串)。我需要这个列表,以便在单元测试中测试每个可能的组合 例如,如果我有一个列表: var allValues = new List<string>() { "A1", "A2", "A3", "B1", "B2", "C1" } 递归函数可能是获得所有组合的方法,但它似乎比我想象的要难 有什么建议吗 多谢各位 编辑:两种解决方案,带或不带递归: public class Combi

我想生成一个字符串列表的所有可能组合的列表(实际上是一个对象列表,但为了简单起见,我们将使用字符串)。我需要这个列表,以便在单元测试中测试每个可能的组合

例如,如果我有一个列表:

  var allValues = new List<string>() { "A1", "A2", "A3", "B1", "B2", "C1" }
递归函数可能是获得所有组合的方法,但它似乎比我想象的要难

有什么建议吗

多谢各位

编辑:两种解决方案,带或不带递归:

public class CombinationGenerator<T>
{
    public IEnumerable<List<T>> ProduceWithRecursion(List<T> allValues) 
    {
        for (var i = 0; i < (1 << allValues.Count); i++)
        {
            yield return ConstructSetFromBits(i).Select(n => allValues[n]).ToList();
        }
    }

    private IEnumerable<int> ConstructSetFromBits(int i)
    {
        var n = 0;
        for (; i != 0; i /= 2)
        {
            if ((i & 1) != 0) yield return n;
            n++;
        }
    }

    public List<List<T>> ProduceWithoutRecursion(List<T> allValues)
    {
        var collection = new List<List<T>>();
        for (int counter = 0; counter < (1 << allValues.Count); ++counter)
        {
            List<T> combination = new List<T>();
            for (int i = 0; i < allValues.Count; ++i)
            {
                if ((counter & (1 << i)) == 0)
                    combination.Add(allValues[i]);
            }

            // do something with combination
            collection.Add(combination);
        }
        return collection;
    }
}
公共类组合生成器
{
公共IEnumerable ProduceWithRecursion(列出所有值)
{
对于(var i=0;i<(1所有值[n])。ToList();
}
}
私有IEnumerable ConstructionSetFromBits(int i)
{
var n=0;
对于(;i!=0;i/=2)
{
如果((i&1)!=0)收益率收益率n;
n++;
}
}
不带递归的公共列表产品(列出所有值)
{
var collection=新列表();

对于(int counter=0;counter<(1如果您想要所有的变体,请查看此项目以了解它是如何实现的

但是你可以使用它,因为它是开源的

例如:

var allValues = new List<string>() { "A1", "A2", "A3", "B1", "B2", "C1" };
List<String> result = new List<String>();
var indices = Enumerable.Range(1, allValues.Count);
foreach (int lowerIndex in indices)
{
    var partVariations = new Facet.Combinatorics.Variations<String>(allValues, lowerIndex);
    result.AddRange(partVariations.Select(p => String.Join(" ", p)));
}

var length = result.Count;  // 1956
var allValues=newlist(){“A1”、“A2”、“A3”、“B1”、“B2”、“C1”};
列表结果=新列表();
var指数=可枚举的范围(1,allValues.Count);
foreach(指数中的整数下限指数)
{
var partVariations=新的方面。组合学。变体(AllValue,lowerIndex);
AddRange(partVariations.Select(p=>String.Join(“,p));
}
var length=result.Count;//1956

类似的任务在下面的帖子中完成:


希望有帮助。

您可以手动输入,使用n位二进制数自然对应于n元素集的子集这一事实

private IEnumerable<int> constructSetFromBits(int i)
{
    for (int n = 0; i != 0; i /= 2, n++)
    {
        if ((i & 1) != 0)
            yield return n;
    }
}

List<string> allValues = new List<string>()
        { "A1", "A2", "A3", "B1", "B2", "C1" };

private IEnumerable<List<string>> produceEnumeration()
{
    for (int i = 0; i < (1 << allValues.Count); i++)
    {
        yield return
            constructSetFromBits(i).Select(n => allValues[n]).ToList();
    }
}

public List<List<string>> produceList()
{
    return produceEnumeration().ToList();
}
private IEnumerable ConstructionSetFromBits(int i)
{
对于(int n=0;i!=0;i/=2,n++)
{
如果((i&1)!=0)
收益率n;
}
}
List allValues=新列表()
{“A1”、“A2”、“A3”、“B1”、“B2”、“C1”};
私有IEnumerable produceEnumeration()
{
对于(int i=0;i<(1所有值[n])。ToList();
}
}
公共列表产品列表()
{
return produceEnumeration().ToList();
}

一个递归解决方案。从下面代码中的
所有组合
,您将获得所有可能的组合。 逻辑:

  • 从一个元素开始
  • 用它生成所有可能的组合
  • 移动到下一个元素并再次从步骤2开始
  • 代码:

    公共类组合
    {
    私有IEnumerable列表{get;set;}
    私有整数长度;
    私有列表_所有组合;
    公共组合(IEnumerable\u列表)
    {
    列表=_列表;
    长度=_list.Count();
    _allCombination=新列表();
    }
    公共IEnumerable所有组合
    {
    得到
    {
    GenerateComposition(默认值(int),Enumerable.Empty());
    返回所有组合;
    }
    }
    私有void-GenerateCombination(int位置,IEnumerable-previous组合)
    {
    for(int i=位置;i<长度;i++)
    {
    var currentCombination=新列表();
    currentCombination.AddRange(以前的组合);
    currentCombination.Add(列表元素地址(i));
    _allcomposition.Add(当前组合);
    发电机组合(i+1,电流组合);
    }
    }
    }
    
    我知道这不是你想要的,但是微软有一个beta版的系统,可以为你自动生成输入组合。它叫Pex:想象一个二进制计数器。这应该可以让你开始。你可能的重复不需要递归:事实上,递归甚至不需要,太好了!不鼓励只使用链接的答案堆栈溢出,因为链接可以中断,并且它们链接的资源可以改变。考虑这里总结链接的相关部分。此外,链接的答案是用于生成排列,而不是组合。
    private IEnumerable<int> constructSetFromBits(int i)
    {
        for (int n = 0; i != 0; i /= 2, n++)
        {
            if ((i & 1) != 0)
                yield return n;
        }
    }
    
    List<string> allValues = new List<string>()
            { "A1", "A2", "A3", "B1", "B2", "C1" };
    
    private IEnumerable<List<string>> produceEnumeration()
    {
        for (int i = 0; i < (1 << allValues.Count); i++)
        {
            yield return
                constructSetFromBits(i).Select(n => allValues[n]).ToList();
        }
    }
    
    public List<List<string>> produceList()
    {
        return produceEnumeration().ToList();
    }
    
    public class Combination<T>
    {
        private IEnumerable<T> list { get; set; }
        private int length;
        private List<IEnumerable<T>> _allCombination;
    
        public Combination(IEnumerable<T> _list)
        {
            list = _list;
            length = _list.Count();
    
            _allCombination = new List<IEnumerable<T>>();
        }
    
        public IEnumerable<IEnumerable<T>> AllCombinations
        {
            get
            {
                GenerateCombination(default(int), Enumerable.Empty<T>());
    
                return _allCombination;
            }
        }
    
        private void GenerateCombination(int position, IEnumerable<T> previousCombination)
        {
            for (int i = position; i < length; i++)
            {
                var currentCombination = new List<T>();
                currentCombination.AddRange(previousCombination);
                currentCombination.Add(list.ElementAt(i));
    
                _allCombination.Add(currentCombination);
    
                GenerateCombination(i + 1, currentCombination);
    
            }
        }
    }