Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/260.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#_Algorithm_Combinations - Fatal编程技术网

C# 值列表的所有可能组合

C# 值列表的所有可能组合,c#,algorithm,combinations,C#,Algorithm,Combinations,我的C#程序中有一个整数列表list。但是,我只知道在运行时列表中的项目数 让我们说,为了简单起见,我的列表是{1,2,3} 现在我需要生成所有可能的组合,如下所示 {1, 2, 3} {1, 2} {1, 3} {2, 3} {1} {2} {3} 有人能帮忙吗?首先,给定一组n个元素,计算出其中k个元素的所有组合(nCk)。您必须将k的值从1更改为n以满足您的要求 有关生成组合的C#代码,请参见此 如果您对自己开发组合算法感兴趣,请在有大量相关资料链接的地方检查此项。尝试以下方法: sta

我的C#程序中有一个整数列表
list
。但是,我只知道在运行时列表中的项目数

让我们说,为了简单起见,我的列表是
{1,2,3}
现在我需要生成所有可能的组合,如下所示

{1, 2, 3}
{1, 2}
{1, 3}
{2, 3}
{1}
{2}
{3}

有人能帮忙吗?

首先,给定一组n个元素,计算出其中k个元素的所有组合(nCk)。您必须将k的值从1更改为n以满足您的要求

有关生成组合的C#代码,请参见此

如果您对自己开发组合算法感兴趣,请在有大量相关资料链接的地方检查此项。

尝试以下方法:

static void Main(string[] args)
{

    GetCombination(new List<int> { 1, 2, 3 });
}

static void GetCombination(List<int> list)
{
    double count = Math.Pow(2, list.Count);
    for (int i = 1; i <= count - 1; i++)
    {
        string str = Convert.ToString(i, 2).PadLeft(list.Count, '0');
        for (int j = 0; j < str.Length; j++)
        {
            if (str[j] == '1')
            {
                Console.Write(list[j]);
            }
        }
        Console.WriteLine();
    }
}
static void Main(字符串[]args)
{
getcomposition(新列表{1,2,3});
}
静态void getcomposition(列表)
{
double count=Math.Pow(2,list.count);

对于(inti=1;i另一个使用Linq和递归的解决方案

static void Main(string[] args)
    {
        List<List<long>> result = new List<List<long>>();

        List<long> set = new List<long>() { 1, 2, 3, 4 };

        GetCombination<long>(set, result);

        result.Add(set);

        IOrderedEnumerable<List<long>> sorted = result.OrderByDescending(s => s.Count);

        sorted.ToList().ForEach(l => { l.ForEach(l1 => Console.Write(l1 + " ")); Console.WriteLine(); });
    }

    private static void GetCombination<T>(List<T> set, List<List<T>> result)
    {
        for (int i = 0; i < set.Count; i++)
        {
            List<T> temp = new List<T>(set.Where((s, index) => index != i));

            if (temp.Count > 0 && !result.Where(l => l.Count == temp.Count).Any(l => l.SequenceEqual(temp)))
            {
                result.Add(temp);

                GetCombination<T>(temp, result);
            }
        }
    }
static void Main(字符串[]args)
{
列表结果=新列表();
列表集=新列表(){1,2,3,4};
获取组合(集合、结果);
结果:添加(集合);
IOrderedEnumerable sorted=result.OrderByDescending(s=>s.Count);
sorted.ToList().ForEach(l=>{l.ForEach(l1=>Console.Write(l1+));Console.WriteLine();});
}
私有静态void getcomposition(列表集、列表结果)
{
for(int i=0;i索引!=i));
if(temp.Count>0&&!result.Where(l=>l.Count==temp.Count).Any(l=>l.SequenceEqual(temp)))
{
结果。添加(温度);
获取组合(临时、结果);
}
}
}

对于涉及字符串或整数的组合/置换问题,我们可以使用递归

public static void Main(string[] args)
{
    IntegerList = new List<int> { 1, 2, 3, 4 };

    PrintAllCombination(default(int), default(int));
}

public static List<int> IntegerList { get; set; }

public static int Length { get { return IntegerList.Count; } }

public static void PrintAllCombination(int position, int prefix)
{
    for (int i = position; i < Length; i++)
    {
        Console.WriteLine(prefix * 10 + IntegerList[i]);
        PrintAllCombination(i + 1, prefix * 10 + IntegerList[i]);
    }

}
publicstaticvoidmain(字符串[]args)
{
整数列表=新列表{1,2,3,4};
PrintAllCombination(默认值(int)、默认值(int));
}
公共静态列表整数列表{get;set;}
公共静态整数长度{get{return IntegerList.Count;}}
公共静态void PrintAllCombination(int位置,int前缀)
{
for(int i=位置;i<长度;i++)
{
Console.WriteLine(前缀*10+整数列表[i]);
PrintAllCombination(i+1,前缀*10+整数列表[i]);
}
}

这里有两个针对强类型列表的通用解决方案,它们将返回列表成员的所有唯一组合(如果您能用更简单的代码解决这个问题,我向您致敬):

//递归
公共静态列表GetAllCombos(列表)
{
列表结果=新列表();
//头
结果.添加(新列表());
result.Last().Add(列表[0]);
如果(list.Count==1)
返回结果;
//尾巴
List tailCombos=GetAllCombos(List.Skip(1.ToList());
tailCombos.ForEach(combo=>
{
结果.添加(新列表(组合));
combo.Add(列表[0]);
结果.添加(新列表(组合));
});
返回结果;
}
//迭代,使用“i”作为位掩码选择每个组合成员
公共静态列表GetAllCombos(列表)
{
int comboCount=(int)Math.Pow(2,list.Count)-1;
列表结果=新列表();
对于(int i=1;i>j)%2!=0)
result.Last().Add(list[j]);
}
}
返回结果;
}
//示例用法
List combos=GetAllCombos(新的int[]{1,2,3}.ToList());

这里有一个使用递归的通用解决方案

public static ICollection<ICollection<T>> Permutations<T>(ICollection<T> list) {
    var result = new List<ICollection<T>>();
    if (list.Count == 1) { // If only one possible permutation
        result.Add(list); // Add it and return it
        return result;
    }
    foreach (var element in list) { // For each element in that list
        var remainingList = new List<T>(list);
        remainingList.Remove(element); // Get a list containing everything except of chosen element
        foreach (var permutation in Permutations<T>(remainingList)) { // Get all possible sub-permutations
            permutation.Add(element); // Add that element
            result.Add(permutation);
        }
    }
    return result;
}
公共静态ICollection排列(ICollection列表){
var result=新列表();
if(list.Count==1){//如果只有一个可能的置换
result.Add(list);//添加并返回
返回结果;
}
foreach(列表中的var元素){//对于该列表中的每个元素
var remainingList=新列表(列表);
remainingList.Remove(element);//获取一个包含除所选元素之外的所有内容的列表
foreach(置换中的var置换(remainglist)){//获取所有可能的子置换
permutation.Add(元素);//添加该元素
结果。添加(排列);
}
}
返回结果;
}

我知道这是一篇老文章,但有人可能会觉得这很有帮助。

这个答案使用了与ojlovecd相同的算法,并且(对于他的迭代解)jaolho。我唯一要添加的是一个选项,用于过滤组合中最少数量的项目的结果。例如,如果您只对包含至少两个项目的组合感兴趣,这可能会很有用

编辑:根据@user3610374的请求,已添加最大项数的筛选器

编辑2:正如@stannius所建议的,该算法已被更改,以使其在不需要所有组合的情况下更有效

  /// <summary>
  /// Method to create lists containing possible combinations of an input list of items. This is 
  /// basically copied from code by user "jaolho" on this thread:
  /// http://stackoverflow.com/questions/7802822/all-possible-combinations-of-a-list-of-values
  /// </summary>
  /// <typeparam name="T">type of the items on the input list</typeparam>
  /// <param name="inputList">list of items</param>
  /// <param name="minimumItems">minimum number of items wanted in the generated combinations, 
  ///                            if zero the empty combination is included,
  ///                            default is one</param>
  /// <param name="maximumItems">maximum number of items wanted in the generated combinations,
  ///                            default is no maximum limit</param>
  /// <returns>list of lists for possible combinations of the input items</returns>
  public static List<List<T>> ItemCombinations<T>(List<T> inputList, int minimumItems = 1, 
                                                  int maximumItems = int.MaxValue)
  {
     int nonEmptyCombinations = (int)Math.Pow(2, inputList.Count) - 1;
     List<List<T>> listOfLists = new List<List<T>>(nonEmptyCombinations + 1);

     // Optimize generation of empty combination, if empty combination is wanted
     if (minimumItems == 0)
        listOfLists.Add(new List<T>());

     if (minimumItems <= 1 && maximumItems >= inputList.Count)
     {
        // Simple case, generate all possible non-empty combinations
        for (int bitPattern = 1; bitPattern <= nonEmptyCombinations; bitPattern++)
           listOfLists.Add(GenerateCombination(inputList, bitPattern));
     }
     else
     {
        // Not-so-simple case, avoid generating the unwanted combinations
        for (int bitPattern = 1; bitPattern <= nonEmptyCombinations; bitPattern++)
        {
           int bitCount = CountBits(bitPattern);
           if (bitCount >= minimumItems && bitCount <= maximumItems)
              listOfLists.Add(GenerateCombination(inputList, bitPattern));
        }
     }

     return listOfLists;
  }

  /// <summary>
  /// Sub-method of ItemCombinations() method to generate a combination based on a bit pattern.
  /// </summary>
  private static List<T> GenerateCombination<T>(List<T> inputList, int bitPattern)
  {
     List<T> thisCombination = new List<T>(inputList.Count);
     for (int j = 0; j < inputList.Count; j++)
     {
        if ((bitPattern >> j & 1) == 1)
           thisCombination.Add(inputList[j]);
     }
     return thisCombination;
  }

  /// <summary>
  /// Sub-method of ItemCombinations() method to count the bits in a bit pattern. Based on this:
  /// https://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetKernighan
  /// </summary>
  private static int CountBits(int bitPattern)
  {
     int numberBits = 0;
     while (bitPattern != 0)
     {
        numberBits++;
        bitPattern &= bitPattern - 1;
     }
     return numberBits;
  }
//
///方法创建包含项目输入列表的可能组合的列表。这是
///基本上是从用户“jaolho”在此线程上的代码复制的:
/// http://stackoverflow.com/questions/7802822/all-possible-combinations-of-a-list-of-values
/// 
///输入列表中项目的类型
///项目清单
///生成的组合中需要的最小项目数,
///如果为零,则包括空组合,
///默认值为1
///生成的组合中需要的最大项数,
///默认值没有最大限制
///输入项可能组合的列表列表
公共静态列表项组合(列表输入列表,int最小项=1,
int maximumItems=int.MaxValue)
{
int nonEmptyCombinations=(int)Math.Pow(2,inputList.Count)-1;
List listOfLists=新列表(非空组合+1);
//优化空com的生成
  /// <summary>
  /// Method to create lists containing possible combinations of an input list of items. This is 
  /// basically copied from code by user "jaolho" on this thread:
  /// http://stackoverflow.com/questions/7802822/all-possible-combinations-of-a-list-of-values
  /// </summary>
  /// <typeparam name="T">type of the items on the input list</typeparam>
  /// <param name="inputList">list of items</param>
  /// <param name="minimumItems">minimum number of items wanted in the generated combinations, 
  ///                            if zero the empty combination is included,
  ///                            default is one</param>
  /// <param name="maximumItems">maximum number of items wanted in the generated combinations,
  ///                            default is no maximum limit</param>
  /// <returns>list of lists for possible combinations of the input items</returns>
  public static List<List<T>> ItemCombinations<T>(List<T> inputList, int minimumItems = 1, 
                                                  int maximumItems = int.MaxValue)
  {
     int nonEmptyCombinations = (int)Math.Pow(2, inputList.Count) - 1;
     List<List<T>> listOfLists = new List<List<T>>(nonEmptyCombinations + 1);

     // Optimize generation of empty combination, if empty combination is wanted
     if (minimumItems == 0)
        listOfLists.Add(new List<T>());

     if (minimumItems <= 1 && maximumItems >= inputList.Count)
     {
        // Simple case, generate all possible non-empty combinations
        for (int bitPattern = 1; bitPattern <= nonEmptyCombinations; bitPattern++)
           listOfLists.Add(GenerateCombination(inputList, bitPattern));
     }
     else
     {
        // Not-so-simple case, avoid generating the unwanted combinations
        for (int bitPattern = 1; bitPattern <= nonEmptyCombinations; bitPattern++)
        {
           int bitCount = CountBits(bitPattern);
           if (bitCount >= minimumItems && bitCount <= maximumItems)
              listOfLists.Add(GenerateCombination(inputList, bitPattern));
        }
     }

     return listOfLists;
  }

  /// <summary>
  /// Sub-method of ItemCombinations() method to generate a combination based on a bit pattern.
  /// </summary>
  private static List<T> GenerateCombination<T>(List<T> inputList, int bitPattern)
  {
     List<T> thisCombination = new List<T>(inputList.Count);
     for (int j = 0; j < inputList.Count; j++)
     {
        if ((bitPattern >> j & 1) == 1)
           thisCombination.Add(inputList[j]);
     }
     return thisCombination;
  }

  /// <summary>
  /// Sub-method of ItemCombinations() method to count the bits in a bit pattern. Based on this:
  /// https://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetKernighan
  /// </summary>
  private static int CountBits(int bitPattern)
  {
     int numberBits = 0;
     while (bitPattern != 0)
     {
        numberBits++;
        bitPattern &= bitPattern - 1;
     }
     return numberBits;
  }
protected List<List<T>> AllCombos<T>(Func<List<T>, List<T>, bool> comparer, params T[] items)
    {
        List<List<T>> results = new List<List<T>>();
        List<T> workingWith = items.ToList();
        results.Add(workingWith);
        items.ToList().ForEach((x) =>
        {
            results.Add(new List<T>() { x });
        });
        for (int i = 0; i < workingWith.Count(); i++)
        {
            T removed = workingWith[i];
            workingWith.RemoveAt(i);
            List<List<T>> nextResults = AllCombos2(comparer, workingWith.ToArray());
            results.AddRange(nextResults);
            workingWith.Insert(i, removed);
        }
        results = results.Where(x => x.Count > 0).ToList();
        for (int i = 0; i < results.Count; i++)
        {
            List<T> list = results[i];
            if (results.Where(x => comparer(x, list)).Count() > 1)
            {
                results.RemoveAt(i);
            }
        }

        return results;
    }

    protected List<List<T>> AllCombos2<T>(Func<List<T>, List<T>, bool> comparer, params T[] items)
    {
        List<List<T>> results = new List<List<T>>();
        List<T> workingWith = items.ToList();
        if (workingWith.Count > 1)
        {
            results.Add(workingWith);
        }
        for (int i = 0; i < workingWith.Count(); i++)
        {
            T removed = workingWith[i];
            workingWith.RemoveAt(i);
            List<List<T>> nextResults = AllCombos2(comparer, workingWith.ToArray());
            results.AddRange(nextResults);
            workingWith.Insert(i, removed);
        }
        results = results.Where(x => x.Count > 0).ToList();
        for (int i = 0; i < results.Count; i++)
        {
            List<T> list = results[i];
            if (results.Where(x => comparer(x, list)).Count() > 1)
            {
                results.RemoveAt(i);
            }
        }

        return results;
    }
public class CombinationGenerator{
    private readonly Dictionary<int, int> currentIndexesWithLevels = new Dictionary<int, int>();
    private readonly LinkedList<List<int>> _combinationsList = new LinkedList<List<int>>();
    private readonly int _combinationLength;

    public CombinationGenerator(int combinationLength)
    {
        _combinationLength = combinationLength;
    }

    private void InitializeLevelIndexes(List<int> list)
    {
        for (int i = 0; i < _combinationLength; i++)
        {
            currentIndexesWithLevels.Add(i+1, i);
        }
    }

    private void UpdateCurrentIndexesForLevels(int level)
    {
        int index;
        if (level == 1)
        {
            index = currentIndexesWithLevels[level];
            for (int i = level; i < _combinationLength + 1; i++)
            {
                index = index + 1;
                currentIndexesWithLevels[i] = index;
            }
        }
        else
        {
            int previousLevelIndex;
            for (int i = level; i < _combinationLength + 1; i++)
            {
                if (i > level)
                {
                    previousLevelIndex = currentIndexesWithLevels[i - 1];
                    currentIndexesWithLevels[i] = previousLevelIndex + 1;
                }
                else
                {
                    index = currentIndexesWithLevels[level];
                    currentIndexesWithLevels[i] = index + 1;
                }
            }
        }
    }

    public void FindCombinations(List<int> list, int level, Stack<int> stack)
    {
        int currentIndex;
        InitializeLevelIndexes(list);
        while (true)
        {
            currentIndex = currentIndexesWithLevels[level];
            bool levelUp = false;          
            for (int i = currentIndex; i < list.Count; i++)
            {
                if (level < _combinationLength)
                {
                    currentIndex = currentIndexesWithLevels[level];
                    MoveToUpperLevel(ref level, stack, list, currentIndex);
                    levelUp = true;
                    break;
                }
                levelUp = false;
                stack.Push(list[i]);
                if (stack.Count == _combinationLength)
                {
                    AddCombination(stack);
                    stack.Pop();
                }                                                                                 
            }

            if (!levelUp)
            {
                MoveToLowerLevel(ref level, stack, list, ref currentIndex);
                while (currentIndex >= list.Count - 1)
                {
                    if (level == 1)
                    {
                        AdjustStackCountToCurrentLevel(stack, level);
                        currentIndex = currentIndexesWithLevels[level];
                        if (currentIndex >= list.Count - 1)
                        {
                            return;
                        }
                        UpdateCurrentIndexesForLevels(level);
                    }
                    else
                    {
                        MoveToLowerLevel(ref level, stack, list, ref currentIndex);
                    }
              }
          }                               
       }
    }

    private void AddCombination(Stack<int> stack)
    {
        List<int> listNew = new List<int>();
        listNew.AddRange(stack);
        _combinationsList.AddLast(listNew);
    }

    private void MoveToUpperLevel(ref int level, Stack<int> stack, List<int> list, int index)
    {
        stack.Push(list[index]);
        level++;
    }

    private void MoveToLowerLevel(ref int level, Stack<int> stack, List<int> list, ref int currentIndex)
    {
        if (level != 1)
        {
            level--;
        }
        AdjustStackCountToCurrentLevel(stack, level);
        UpdateCurrentIndexesForLevels(level);
        currentIndex = currentIndexesWithLevels[level];
    }

    private void AdjustStackCountToCurrentLevel(Stack<int> stack, int currentLevel)
    {
        while (stack.Count >= currentLevel)
        {
            if (stack.Count != 0)
                stack.Pop();
        }
    }

    public void PrintPermutations()
    {
        int count = _combinationsList.Where(perm => perm.Count() == _combinationLength).Count();
        Console.WriteLine("The number of combinations is " + count);
    }

}
static void Main(string[] args)
{
     Combos(new [] { 1, 2, 3 });
}

static void Combos(int[] arr)
{
    for (var i = 0; i <= Math.Pow(2, arr.Length); i++)
    {
        Console.WriteLine();
        var j = i;
        var idx = 0;
        do 
        {
            if ((j & 1) == 1) Console.Write($"{arr[idx]} ");
        } while ((j >>= 1) > 0 && ++idx < arr.Length);
    }
}
static void Main(string[] args)
{
    foreach (var vals in Combos(new[] { "0", "1", "2", "3" }).Where(v => v.Skip(1).Any() && !v.Skip(2).Any()))
        Console.WriteLine(string.Join(", ", vals));
}

static IEnumerable<IEnumerable<T>> Combos<T>(T[] arr)
{
    IEnumerable<T> DoQuery(long j, long idx)
    {
        do
        {
            if ((j & 1) == 1) yield return arr[idx];
        } while ((j >>= 1) > 0 && ++idx < arr.Length);
    }
    for (var i = 0; i < Math.Pow(2, arr.Length); i++)
        yield return DoQuery(i, 0);
}
public static IEnumerable<T[]> Combinations<T>(IEnumerable<T> source) {
  if (null == source)
    throw new ArgumentNullException(nameof(source));

  T[] data = source.ToArray();

  return Enumerable
    .Range(0, 1 << (data.Length))
    .Select(index => data
       .Where((v, i) => (index & (1 << i)) != 0)
       .ToArray());
}
  var data = new char[] { 'A', 'B', 'C' };

  var result = Combinations(data);

  foreach (var item in result)
    Console.WriteLine($"[{string.Join(", ", item)}]);
[]
[A]
[B]
[A, B]
[C]
[A, C]
[B, C]
[A, B, C]
public static List<List<int>> GetCombination(List<int> lst, int index, int count)
{
    List<List<int>> combinations = new List<List<int>>();
    List<int> comb;
    if (count == 0 || index == lst.Count)
    {
        return null;
    }
    for (int i = index; i < lst.Count; i++)
    {
        comb = new List<int>();
        comb.Add(lst.ElementAt(i));
        combinations.Add(comb);
        var rest = GetCombination(lst,i + 1, count - 1);
        if (rest != null)
        {
            foreach (var item in rest)
            {
                combinations.Add(comb.Union(item).ToList());
            }
        }
    }
    return combinations;
}
List<int> lst= new List<int>(new int[]{ 1, 2, 3, 4 });
var combinations = GetCombination(lst, 0, lst.Length)
    static void Main(string[] args)
    {
        GetCombination(new List<int> { 1, 2, 3 });
    }


    private static void GetCombination(List<int> list)
    {
        double count = Math.Pow(2, list.Count);
        for (int i = 1; i <= count - 1; i++)
        {
            for (int j = 0; j < list.Count; j++)
            {
                int b = i & (1 << j);
                if (b > 0)
                {
                    Console.Write(list[j]);
                }
            }
            Console.WriteLine();
        }
    }
private static List<string> GetCombinations(List<string> elements)
{
    List<string> combinations = new List<string>();
    combinations.AddRange(elements);
    for (int i = 0; i < elements.Count - 1; i++)
    {
        combinations = (from combination in combinations
                        join element in elements on 1 equals 1
                        let value = string.Join(string.Empty, $"{combination}{element}".OrderBy(c => c).Distinct())
                        select value).Distinct().ToList();
    }

    return combinations;
}
List<string> elements = new List<string> { "1", "2", "3" };
List<string> combinations = GetCombinations(elements);

foreach (string combination in combinations)
{
    System.Console.Write(combination);
}