c# - 如何将组合硬编码片段转换为递归函数?

标签 c# algorithm recursion combinations hardcoded

目前我有这个代码片段,它正在做我想做的事情:给定一些对象,它会创建它们之间所有可能的组合。

在此示例中,假设有 4 个对象(0、1、2 和 3),创建了 4 个对象的所有可能组合(0、1、2、3、01(0 和 1 的组合) , 02, 03, 12, 13, 23, 012, 013, 023, 123 和 0123)。

应该注意,有 2^4 - 1 = 15 种组合,通常有 2^number of objects - 1 种组合。

使用此代码创建的对象的顺序是:0 -> 01 -> 012 -> 0123 -> 013 -> 02 -> 023 -> 03 -> 1 -> 12 -> 123 -> 13 -> 2 -> 23 -> 3

我获取初始对象的方式和它们的数量在代码的其他地方定义。

int count = 4; //this is gotten elsewhere
int currPos = 0;
var objects = new Object[(2^count)-1];

for (int i = 0; i < count; i++) //loop that creates combinations of only one object
{
    Object obj = new Object(...);
    objects[currPos] = obj;
    currPos += 1;

    for (int j = i + 1; j < count; j++) //loop that creates combinations of two objects
    {
        Object obj = new Object(...);
        objects[currPos] = obj;
        currPos += 1;

        for (int k = j + 1; k < count; k++) //loop that creates combinations of three objects
        {
            Object obj = new Object(...);
            objects[currPos] = obj;
            currPos += 1;

            for (int l = k + 1; l < count; l++) //loop that creates combinations of four objects
            {
                Object obj = new Object(...);
                objects[currPos] = obj;
                currPos += 1;
            }
        }
    }
}

尽管给出了正确的结果,但这是硬编码的,因此我正在寻找一种方法将其更改为递归函数(但保持其功能),对象数量(这也决定了最大组合,四个示例)作为参数传递。

我一直在尝试做类似下面的代码但没有结果,主要是因为我似乎无法在必要时转到“上一个”循环,例如从 0123 到 013。

    int count = 4;
    int currPos = 0;
    var objects = new Object[(2^count)-1];
    combinations(count, 0, currPos, objects); //called elsewhere

    private void combinations(int numberOfObjects, int j, int count, int currPos, Object[] objects)

    {   
        if (numberOfObjects == count)
        {
            for (int k = j; k < count; k++)
            {
                Object obj = new Object(...);
                objects[currPos] = obj;
                currPos += 1;
                generateCombinations(numberOfObjects - 1, j + 1, count, currPos, objects);
            }
        }

        if (numberOfObjects < count)
        {
            for (int l = j; l < count; l++)
            {
                Object obj = new Object(...);
                objects[currPos] = obj;
                currPos += 1;

                (...)

                generateCombinations(..., ..., count, currPos, objects);
             }
        }
    }

最佳答案

这是你追求的那种东西吗?

public IEnumerable<string> GetCombinations(IEnumerable<string> source)
{
    if (source == null || !source.Any())
    {
        return Enumerable.Empty<string>();
    }
    else if (source.Skip(1).Any())
    {
        return new string[] { null, source.First() }.SelectMany(x => GetCombinations(source.Skip(1)), (x, y) => x + y);
    }
    else
    {
        return new string[] { null, source.First() };
    }
}

我可以这样使用它:

var combinations = GetCombinations(new[] { "0", "1", "2", });

我得到了这个结果:

null  
2 
1 
12 
0 
02 
01 
012 

关于c# - 如何将组合硬编码片段转换为递归函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38492698/

相关文章:

C#,是否可以避免定义私有(private)字段并仍然在公共(public)字段上使用 set/get?

C# 查询日期时间

algorithm - 最大有序比【分而治之算法】

algorithm - 建议分析算法

c# - 将参数传递给 SharePoint 计时器作业

c# - 有没有一种方法可以在不使用队列或 blob 存储的情况下触发 webjob?

java - 用 Java 制作 3D 迷宫

python - 匹配两个DataFrame的更快方法

java - Java中的凯撒密码带有递归?

java - 使用递归来获取数组的子集。 C++ 和 Java 给我不同的结果