列表的独特组合

ano*_*ery 9 c# 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

这可以做它应该做的事情,但它返回所有排列,无论它们是唯一的.我试图让我的头围绕这个代码的哪一块(如果有的话)改变以获得唯一值.或者是实现此功能的更好方法?

Dan*_*rth 16

试试这个:

void Main()
{
    var list = new List<string> { "a", "b", "c", "d", "e" };
    var result = GetPermutations(list, 3);
}

IEnumerable<IEnumerable<T>> GetPermutations<T>(IEnumerable<T> items, int count)
{
    int i = 0;
    foreach(var item in items)
    {
        if(count == 1)
            yield return new T[] { item };
        else
        {
            foreach(var result in GetPermutations(items.Skip(i + 1), count - 1))
                yield return new T[] { item }.Concat(result);
        }

        ++i;
    }
}
Run Code Online (Sandbox Code Playgroud)

对于2的计数,它返回:

a, b
a, c
a, d
a, e
b, c
b, d
b, e
c, d
c, e
d, e
Run Code Online (Sandbox Code Playgroud)

对于3的计数,它返回:

a, b, c
a, b, d
a, b, e
a, c, d
a, c, e
a, d, e
b, c, d
b, c, e
b, d, e 
c, d, e
Run Code Online (Sandbox Code Playgroud)

这是你期望的吗?


Guf*_*ffa 3

实现中的剩余项目列表包含除当前起始项目之外的所有项目。

获取起始项目之后的项目:

IEnumerable<T> remainingItems = list.Skip(startingElementIndex + 1);
Run Code Online (Sandbox Code Playgroud)