简体   繁体   English

C#中的部分组合/置换-例如A,B,C = {A,B},{A,C},{B,C}

[英]Partial Combinations/Permutations in C# - e.g. A,B,C = {A,B}, {A,C}, {B,C}

There are many brilliant implementations for Permutations - I chose Sam's answer in the link. 置换有许多出色的实现-我在链接中选择了Sam的答案。

I also understand there is a difference between permutations and combinations but I don't know how to word this properly. 我也了解排列和组合之间的区别,但是我不知道如何正确地表达。

I need guidance on getting all unique partial combinations please, eg 我需要获得所有唯一的部分组合的指导,例如

A,B,C = {A,B}, {A,C}, {B,C}
A,B,C,D = {A,B,C},{A,B,D},{B,C,D},{A,C,D},{A,B}, {A,C}, {B,C}

From here I will pass this to the permutation function to get me all available permutations, eg {A,B}, {B,A}, {A,C}, {C,A} etc. 从这里,我将其传递给置换函数,以获取所有可用的置换,例如{A,B}, {B,A}, {A,C}, {C,A}等。

How can I get these (partial) subsets of the greater set? 如何获得更大集合的这些(部分)子集?

It is quite easy to do recursively. 递归很容易做到。 You go through a virtual tree in the GetSubCombinations function, always returning the set without the current element first and then with the current element. 您遍历GetSubCombinations函数中的虚拟树,总是先返回不带当前元素的集合,然后再返回带当前元素的集合。 On the last level (the first part of the GetSubCombinations function) you generate the lists that are being returned, either including the last element or being empty. 在最后一级( GetSubCombinations函数的第一部分),您将生成要返回的列表,包括最后一个元素或为空。

Code follows: 代码如下:

using System.Collections.Generic;


class Program {
    private static IEnumerable<List<char>> GetSubCombinations(char[] elements, uint startingPos)
    {
        // Leaf condition
        if (startingPos == elements.Length - 1)
        {
            yield return new List<char> {elements[startingPos]};
            yield return new List<char>();
            yield break;
        }

        // node splitting
        foreach (var list in GetSubCombinations(elements, startingPos + 1))
        {
            yield return list;
            list.Add(elements[startingPos]);
            yield return list;
            list.Remove(elements[startingPos]);
        }
    }

    private static IEnumerable<List<char>> GetPartialCombinations(char[] elements)
    {
        foreach (var c in GetSubCombinations(elements, 0))
        {
            // Here you can filter out trivial combinations,
            // e.g. all elements, individual elements and the empty set
            if (c.Count > 1 && c.Count < elements.Length)
                yield return c;
        }
    }


    static void Main(string[] args) {
        char[] elements = new char[] {'A', 'B', 'C'};
        foreach (var combination in GetPartialCombinations(elements))
        {
            foreach (char elem in combination)
                System.Console.Write(elem + ", ");
            System.Console.Write("\n");
        }
        return;
    }

}

The difference between permutation to a combination is that in a permutation the order matters. 排列与组合之间的区别在于排列中的顺序很重要。

From what I understand you want all the Combinations , Thus all combinations that don't fill the exact set (You want to make a subset) 据我了解,您需要所有组合 ,因此所有组合都无法填充确切的组合(您想创建一个子集)

EX: 例如:

So for S = {A,B,C,D} , an example of a partial combination would be {A,C,B} as it doesn't care about the order and it doesn't contain the full set (ie. it is a subset of S) 因此,对于S = {A,B,C,D} ,部分组合的示例为{A,C,B}因为它不关心顺序,也不包含完整的集合(即它是S的子集)

The formula for Combination is N choose K 组合的公式为N choose K

So your set has 4 elements (N) and you want a set of 3 or less (K) 因此,您的集合有4个元素(N),而您希望有3个或更少的元素(K)

So N!/K!(N-K)! 
3: = 4!/3!(4-3)! = (1x2x3x4)/(1x2x3)(1) = 4
2: = 4!/2!(2)! = 1x2x3x4/(1x2x1x2) = 6
1: = 4!/1!(4-1)! = 1x2x3x4/1x2x3 = 4

Thus answer is 14 因此答案是14

If you want some code on how to implement a combination calculation: SOURCE 如果您想要一些有关如何实现组合计算的代码: SOURCE

private 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();
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM