如何使用嵌套for循环和递归来创建字符串组合列表

时间:2016-02-21 08:07:44

标签: c# recursion

我在Key / Value对中有一个SortedList,到目前为止存储了3个这样的条目:

Key: "Shapes" and Value: ["Cube", "Sphere"]
Key: "Colors" and Value: ["Red", "Green"]
Key: "Sizes" and Value: ["Big", "Small"]

我的目标是生成所有字符串组合并将它们存储到另一个列表中:

"Shape:Cube/Colors:Red/Size:Big"
"Shape:Cube/Colors:Red/Size:Small"
"Shape:Cube/Colors:Green/Size:Big"
"Shape:Cube/Colors:Green/Size:Small"
"Shape:Sphere/Colors:Red/Size:Big"
"Shape:Sphere/Colors:Red/Size:Small"
"Shape:Sphere/Colors:Green/Size:Big"
"Shape:Sphere/Colors:Green/Size:Small"

这里需要注意的是,第一个SortedList中可以有N个条目,所以我不能在我的源代码中真正创建for循环。我知道我应该使用递归来解决动态N值的棘手问题。

到目前为止,我只为N = 2个条目提出了一个硬编码解决方案,而且我无法转换为可以处理N个条目的任何值的递归:

for (int ns=0; ns < listFeaturesSuperblock.Values[0].Count; ns++) { 
    for (int nc=0; nc < listFeaturesSuperblock.Values[1].Count; nc++) { 

        //prefab to load
        string str = "PreFabs/Objects/" + listFeaturesSuperblock.Keys[0][ns] + ":" + listFeaturesSuperblock.Values[0][ns] + "/" + listFeaturesSuperblock.Values[1][nc] + ":" + listFeaturesSuperblock.Values[1][nc];
    }
}

有人可以指出我朝着正确的方向前进吗?我应该如何处理这个问题以及我需要学习什么才能更好地编写递归?

谢谢。

2 个答案:

答案 0 :(得分:1)

在您当前的方法中:

List<string> result = new List<string>;

ProcessItems(listFeaturesSuperblock, result);

这是递归方法:

void ProcessItems(SortedList<string, List<string>> data, List<string> result, int level = 0, string prefix = "PreFabs/Objects/")
{
    for (int i = 0; i < data.Values[level].Count; i++)
    {
        string item = prefix + data.Keys[level] + ":" + data.Values[level][i] + "/";
        if (level == data.Values.Count - 1)
            result.Add(item);
        else
            ProcessItems(data, result, level + 1, item);
    }
}

&#39;结果&#39;变量将包含所有排列。

答案 1 :(得分:1)

使用递归是一种安静的方式,这是一种简单的方法。

我们说Dictionary就像你的例子中那样

public static Dictionary<string, List<string>> props = new Dictionary<string, List<string>>(){
    { "Shapes", new List<string>{"Cube", "Sphere"} },
    { "Colors", new List<string>{"Red", "Green"} },
    { "Sizes", new List<string>{"Big", "Small"} }
};

现在我们获取第一个键的所有值并通过它们将它们的值附加到源字符串。因此,对于我们将得到的第一个值

/Shapes:Cube

现在我们对下一个键Colors执行相同操作,结果

/Shapes:Cube/Colors:Red

我们继续它,而有更多未处理的密钥。当没有更多的键时,我们得到了第一个结果字符串

/Shapes:Cube/Colors:Red/Sizes:Big

现在我们需要返回并添加另一个值

的值
/Shapes:Cube/Colors:Red/Sizes:Small

此代码将如下所示

public static List<string> GetObjectPropertiesPermutations(string src, string[] keys, int index) {
    if(index >= keys.Length) {
        return new List<string>() { src };
    }
    var list = new List<string>();
    var key = keys[index];
    foreach(var val in props[key]) {
        var other = GetObjectPropertiesPermutations(src + "/" + key + ":" + val, keys, index + 1);
        list.AddRange(other);
    }
    return list;
}

public static void Main(string[] args)
{
    var perms = GetObjectPropertiesPermutations("", props.Keys.ToArray(), 0);
    foreach(var s in perms) {
        Console.WriteLine(s);
    }
}