如何使用收益返回和递归获得字母的每个组合?
我有几个像这样的字符串列表,可能有几十个列表:
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,然后B1E
,依此类推。到目前为止,我已经编写了这个递归算法:
public void Tester()
{
var 2dList = new List { list1, list2, list3 };
var answer = ReturnString(2dList).ToList();
answer.ForEach(Console.WriteLine);
}
public IEnumerable<string> ReturnString(List<List<string>> list)
{
if (!list.Any())
{
yield return null;
}
else
{
// for each letter in the top-most list...
foreach (var letter in list.First())
{
// get the remaining lists minus the first one
var nextList = list.Where(x => x != list.First()).ToList();
// get the letter and recurse down to find the next
yield return letter + ReturnString(nextList);
}
}
}
但是,我得到的回报是:
AStringGeneration.StringGenerator+<ReturnString>d__11
BStringGeneration.StringGenerator+<ReturnString>d__11
CStringGeneration.StringGenerator+<ReturnString>d__11
StringGeneration
是 ReturnString
所在类的名称。当我输入在 yield return letter + ...
行上的断点,它似乎遍历 A
、B
和 C,但实际上并不递归。我不确定这里发生了什么事。谁能解释一下我的算法有什么问题吗?
I have several lists of strings like so, from a possible list of several dozen:
1: { "A", "B", "C" }
2: { "1", "2", "3" }
3: { "D", "E", "F" }
These three were only picked as an example, and the user can pick from several dozen similar lists with varying number of elements. For another example, this is also a perfectly valid selection for a user:
25: { } // empty
4: { "%", "!", "$", "@" }
16: { "I", "a", "b", "Y" }
8: { ")", "z", "!", "8" }
What I want to do is get every combination of strings possible while keeping the 'order' of the lists. In other words, assuming we're looking at the first list, the first combination will be A1D
, then A1E
, then A1F
, then B1D
, then B1E
, and so on and so forth. So far I've written this recursive algorithm:
public void Tester()
{
var 2dList = new List { list1, list2, list3 };
var answer = ReturnString(2dList).ToList();
answer.ForEach(Console.WriteLine);
}
public IEnumerable<string> ReturnString(List<List<string>> list)
{
if (!list.Any())
{
yield return null;
}
else
{
// for each letter in the top-most list...
foreach (var letter in list.First())
{
// get the remaining lists minus the first one
var nextList = list.Where(x => x != list.First()).ToList();
// get the letter and recurse down to find the next
yield return letter + ReturnString(nextList);
}
}
}
However, what I get in return is this instead:
AStringGeneration.StringGenerator+<ReturnString>d__11
BStringGeneration.StringGenerator+<ReturnString>d__11
CStringGeneration.StringGenerator+<ReturnString>d__11
StringGeneration
is the name of the class that ReturnString
is in. When I put a breakpoint on the yield return letter + ...
line, it seems to iterate through A
, B
, and C
, but doesn't actually recurse. I'm not sure what's going on here. Can anyone explain what is wrong with my algorithm?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您需要枚举迭代器:
这也适用于每次迭代:
另外,我怀疑您可以在此处使用 SelectMany 做一些事情。
You need to enumerate the iterator:
This applies per iteration too:
Also, I suspect you can do something with SelectMany here.
更新:
这是任意版本的概要。稍后我会填写详细信息。
Update:
Here's an outline for an arbitrary version. I'll fill in details later.
调用
ReturnString(lst.Where(l => l.Any())
来跳过空序列。call as
ReturnString(lst.Where(l => l.Any())
to skip empty sequences.