一尘不染

清单的独特组合

algorithm

对此绝对空白。那是那些日子之一。但是我一直在寻找一种解决方案,以获取特定长度的项目列表的唯一组合。例如,给定列表[a,b,c]和长度为2,它将返回[a,b]
[a,c] [b,c],但不返回[b,a] [c,a] [c ,b]

为此,我发现了很多代码,但似乎没有合适的代码。以下代码似乎最合适,我一直在尝试根据自己的需要进行更改:

// Returns an enumeration of enumerators, one for each permutation
// of the input.
public static IEnumerable<IEnumerable<T>> Permute<T>(IEnumerable<T> list, int count)
{
    if (count == 0)
    {
        yield return new T[0];
    }
    else
    {
        int startingElementIndex = 0;
        foreach (T startingElement in list)
        {
            IEnumerable<T> remainingItems = AllExcept(list, startingElementIndex);

            foreach (IEnumerable<T> permutationOfRemainder in Permute(remainingItems, count - 1))
            {
                yield return Concat<T>(
                    new T[] { startingElement },
                    permutationOfRemainder);
            }
            startingElementIndex += 1;
        }
    }
}

// Enumerates over contents of both lists.
public static IEnumerable<T> Concat<T>(IEnumerable<T> a, IEnumerable<T> b)
{
    foreach (T item in a) { yield return item; }
    foreach (T item in b) { yield return item; }
}

// Enumerates over all items in the input, skipping over the item
// with the specified offset.
public static IEnumerable<T> AllExcept<T>(IEnumerable<T> input, int indexToSkip)
{
    int index = 0;
    foreach (T item in input)
    {
        if (index != indexToSkip) yield return item;
        index += 1;
    }
}

这可以完成预期的操作,但是无论所有排列是否唯一,它都将返回所有排列。我试图弄清楚该代码的哪一部分(如果有的话)进行更改以获取唯一值。还是实现此功能的更好方法?


阅读 248

收藏
2020-07-28

共1个答案

一尘不染

实现中的其余项目列表包含当前起始项目以外的所有项目。

获取开始项之后的项:

IEnumerable<T> remainingItems = list.Skip(startingElementIndex + 1);
2020-07-28