做有序排列的有效方法

时间:2017-06-06 14:05:28

标签: c# algorithm permutation

我不知道它是否可能,但我试图在C#中找到一种算法,该算法可以生成一组数字的所有排列,其中包含一些"空的空间"在保持秩序的同时。

示例:

我有一个数组[1,2],我需要所有有序的排列,其中有两个"空格"。 在这种情况下,我将:

[1,2,null,null]
[1,null,2,null]
[1,null,null,2]
[null,1,2,null]
[null,1,null,2]
[null,null,1,2]

我试图包括所有"空白空间"在进行排列之前在数组内部,但它产生了太多我不需要的排列。

在C#中,函数可能是

    private static List<int[]> PermutateWithSpace(this List<int> set, int numberOfEmptySpace)
    {
        // Algorithm which yield all possible permutations of my N "null" inside my set
    }

1 个答案:

答案 0 :(得分:2)

当然,该算法很简单。

假设您有n个数字和m个空值。我们将从空值开始,然后插入数字。

我们要做的第一件事就是找出第一个数字的位置。我们产生0,1,2,... m个空值,然后产生第一个数字。

假设我们在这个排列上产生了x null。现在我们弄清楚第二个数字的去向。我们得到0,1,2,... m - x空值,然后得到第二个数。

等等。

这是否足以提示,或者您是否需要查看算法?

如果你遇到困难:

static IEnumerable<T> Append<T>(this IEnumerable<T> items, T item) 
{
    foreach(var i in items)
        yield return i;
    yield return item;
}

static IEnumerable<IEnumerable<int?>> DoIt(int min, int max, int nulls)
{
    if (min > max)
        yield return Enumerable.Repeat<int?>(null, nulls);
    else
        for(int i = 0; i <= nulls; ++i)
            foreach(var r in DoIt(min + 1, max, nulls - i))
                yield return Enumerable.Repeat<int?>(null, i).Append(min).Concat(r);    
}

或者,更紧凑,采用LINQ风格!

static IEnumerable<IEnumerable<int?>> DoIt(int min, int max, int nulls)
{
    return (min > max) ? 
        new[] { Enumerable.Repeat<int?>(null, nulls) } :
        from i in Enumerable.Range(0, nulls + 1)
        from r in DoIt(min + 1, max, nulls - i)
        select Enumerable.Repeat<int?>(null, i).Append(min).Concat(r);
}