如何获得数组中具有固定数量标志的所有组合

时间:2018-07-14 14:11:40

标签: c# math logic permutation

在这里,我有一个具有特定长度的数组,并且还必须设置特定数目的标志。标志的长度和数量可以根据大小写而变化,因此它们应该是通用的。 示例:

var array = new bool[] { false, false, false, false, false, false };
var numberOfFlags = 2;

我现在想获得所有可能的排列/组合,而必须始终设置2个标志。示例:

1 1 0 0 0 0
0 1 1 0 0 0
0 0 1 1 0 0

但例如:

0 1 0 0 0 1

或者:

0 0 0 1 0 1

我只需要一种获得设置了预定义数量标志的所有可能组合的方法。没有模式或任何东西,只有所有可能的组合。最好使用C#。

我真的很期待一个答案,非常感谢!

3 个答案:

答案 0 :(得分:1)

我在rosettacode.org上找到了它。 (我做了一点修改)。它是非递归的。它仅使用堆栈。每次都会返回相同(修改后)的数组,但是可以根据需要轻松更改。

public static IEnumerable<int[]> Combinations(int n, int k)
{
    var result = new int[k];
    var stack = new Stack<int>();
    stack.Push(0);

    while (stack.Count > 0) {
        int index = stack.Count - 1;
        int value = stack.Pop();

        while (value < n) {
            result[index++] = value++;
            stack.Push(value);

            if (index == k) {
                yield return result;
                break;
            }
        }
    }
}

组合(6,2)将给出:
[0,1],[0,2],[0,3],[0,4],[0,5],[1,2],[1,3],[1,4],[1 ,5],[2,3],[2,4],[2,5],[3,4],[3,5],[4,5]

答案 1 :(得分:0)

可以通过以下方式计算组合数量:

P =(n!)/(a!·b!)

其中 n 是数组的长度, a 是numberOfFlags, b n-a

这是一种实现所需目标的方法:

        bool[] array = new bool[] { false, false, false,false};
        int numberOfFlags = 1;

        int n, a, b,_n,_a,_b;
        n = array.Length;
        _n = n;
        a = numberOfFlags;
        _a = a;
        b = n - a;
        _b = b;

        //Calculate n!
        for (int i = _n - 1; i >= 1; i--)
            n = n * i;

        //Calculate a!
        for (int i = _a - 1; i >= 1; i--)
            a = a * i;

        //Calculate a!
        for (int i = _b - 1; i >= 1; i--)
            b = b * i;

        int NumberOfPermutations = n / (a * b);

------编辑------

此代码仅适用于只有两个可能值的数组。假设我们有3个可能的值,然后:

n =数组的长度

a =第一个值的重复

b =重复第二个值

c = n-(a + b) =第三个值的重复

排列数量可以用 P =(n!)/(a!·b!·c!...) 在代码中,您应该只添加一些变量,一些循环... etvoilà

答案 2 :(得分:0)

对于numberOfFlags = 2来说,这是一个简单的解决方案:

static void Main(string[] args)
{
    var array = new bool[] { false, false, false, false, false, false };

    var length = array.Length;
    for (int i = 0; i < length; i++)
    {
        for (int j = i + 1; j < length; j++)
        {
            var arr = (bool[])array.Clone();
            arr[i] = arr[j] = true;

            arr.ToList().ForEach(s => Console.Write((s ? 1 : 0) + " "));
            Console.WriteLine();
        }
    }
    Console.Read();
}

输出:

1 1 0 0 0 0
1 0 1 0 0 0
1 0 0 1 0 0
1 0 0 0 1 0
1 0 0 0 0 1
0 1 1 0 0 0
0 1 0 1 0 0
0 1 0 0 1 0
0 1 0 0 0 1
0 0 1 1 0 0
0 0 1 0 1 0
0 0 1 0 0 1
0 0 0 1 1 0
0 0 0 1 0 1
0 0 0 0 1 1