如何使用递归获取设置顺序中的每个字符串组合?

时间:2011-07-31 15:06:50

标签: c# algorithm recursion string-concatenation yield-return

这个问题与我之前提出的问题有关,请问:

How do I get every combination of letters using yield return and recursion?

我有几个像这样的字符串列表,从几十个可能的列表:

1: { "A", "B", "C" }
2: { "1", "2", "3" }
3: { "D", "E", "F" }

这三个仅作为示例选择,并且用户可以从具有不同数量的元素的数十个类似列表中进行选择。再举一个例子,这对用户来说也是一个非常有效的选择:

25: { } // empty
 4: { "%", "!", "$", "@" }
16: { "I", "a", "b", "Y" }
 8: { ")", "z", "!", "8" }

我想要做的是在保持列表的“顺序”的同时获得每个字符串组合。换句话说,假设我们正在查看第一个列表,第一个组合将是A1D,然后是A1E,然后是A1F,然后是B1D,然后是{{1 }}, 等等等等。基于我之前提出的问题中提供的答案,我编写了这个有效的递归算法:

B1E

但是,此代码依赖于public void Tester() { var collection = new List { list1, list2, list3 }; var answer = GetStringCombinations(collection).ToList(); answer.ForEach(Console.WriteLine); } private IEnumerable<string> GetStringCombinations(List<List<string>> collection) { // if the collection is empty, return null to stop the recursion if (!collection.Any()) { yield return null; } // recurse down the list, selecting one letter each time else { foreach (var letter in collection.First()) { // get the collection sans the first item var nextCollection = collection.Skip(1).ToList(); // construct the strings using yield return and recursion foreach (var tail in GetStringCombinations(nextCollection)) { yield return letter + tail; } } } } 才能正常工作。如何在不使用yield return关键字的情况下实现此算法,例如,如果我将代码移植到ColdFusion或Ruby(假设它们也没有类似的关键字)?

2 个答案:

答案 0 :(得分:1)

我没有测试它,但应该工作

private List<string> GetStringCombinations(List<List<string>> collection)
{
List<string> ls = new List<string>();

// if the collection is empty, return null to stop the recursion
if (!collection.Any())
{
    return null;
}
// recurse down the list, selecting one letter each time
else
{
    foreach (var letter in collection.First())
    {
        // get the collection sans the first item
        var nextCollection = collection.Skip(1).ToList();

        // construct the strings using yield return and recursion
        foreach (var tail in GetStringCombinations(nextCollection))
        {
            ls.add(letter + tail);
        }
    }
}
return ls;

}

答案 1 :(得分:0)

伪代码:

  Combinations(lists[1..n], start, prefix)
   1. If start = n + 1 then print(prefix)
   2. else then
   3.    for i = 1 to lists[start].length do
   4.       Combinations(lists, start + 1, 
                prefix.append(lists[start][i])

这样的事情应该有用。为获得最佳结果,请使用start =最低数组索引和prefix =空字符串调用上面的内容。通过一些调整,这将很好用。