基于整数重复IEnumerable的排列

时间:2016-11-22 19:25:42

标签: c# permutation ienumerable

我正在尝试在C#上进行IEnumerable排列(带重复)功能。 我已经有一个使用Arrays的函数;

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

它的效果非常好......但是 现在我需要创建IEnumerable函数,它将直接在整数上运行,而不是在数组上运行。例如,如果我称之为;

GetPermsInts(max_val = 1, digits_num = 2) 

我应该得到输出;

00
01
10
11

我尝试在许多方面修改该功能以实现这一目标,但仍然没有运气...... 请有人帮帮我吗?

1 个答案:

答案 0 :(得分:0)

嗯,你可以这样做(假设你想要返回字符串):

IEnumerable<string> EnumeratePermutations(int digits, int length)
{
    var data = new char[length];
    for (int i = 0; i < data.Length; ++i)
    {
        data[i] = '0';
    }

    while (true)
    {
        yield return new string(data);

        char maxChar = (char)('0' + digits);

        for (int index = length - 1; index >= 0; --index)
        {
            if (++data[index] == maxChar)
            {
                for (int i = index; i < data.Length; ++i)
                {
                    data[i] = '0';
                }

                if (index == 0)
                {
                    yield break;
                }
            }
            else
            {
                break;
            }
        }
    }
}

通过这种方式,您可以使用length个不同的字符获取给定digits的任何排列。如果你想要一个大于9的基数,那么你应该添加一些映射来使用所需的字符。

此代码只会以词汇顺序生成使用过的排列。