提供一些上下文:我正在开发一个算法问题构建器,最终用户可以输入变量,为它们分配范围和规则,在公式中使用它们并实现(x)大量的问题。
我目前需要使用变量名[a],[b],[c]等等的键来填充x个元素的x个字典,每个值都是唯一的,每个它们可能存在的范围的可能性;即a = 1 - 100,b = 1 - 50等等。
So 1st dict would be:
[a] = 1
[b] = 1
[c] = 1
2nd dict
[a] = 2
[b] = 1
[c] = 1
是否有一个简单的递归函数可以比迭代函数更好地处理它?</ p>
感谢您的帮助!
答案 0 :(得分:1)
如果我从可以表示您的值范围的结构开始,如下所示:
public struct Range
{
public int Minimum { get; set; }
public int Maximum { get; set; }
}
...然后我可以代表你的输入:
var inputs = new Dictionary<string, Range>()
{
{ "a", new Range() { Minimum = 1, Maximum = 3 } },
{ "b", new Range() { Minimum = 1, Maximum = 2 } },
{ "c", new Range() { Minimum = 1, Maximum = 2 } },
};
...然后我可以像这样构建结果:
Func<IEnumerable<KeyValuePair<string, Range>>, IEnumerable<Dictionary<string, int>>> build = null;
build =
kvps =>
{
if (kvps.Skip(1).Any())
{
return
from kvp in kvps.Take(1)
from n in Enumerable.Range(kvp.Value.Minimum, kvp.Value.Maximum - kvp.Value.Minimum + 1)
from r in build(kvps.Skip(1))
select new[] { new KeyValuePair<string, int>(kvp.Key, n) }.Concat(r).ToDictionary(x => x.Key, x => x.Value);
}
else
{
return
from kvp in kvps
from n in Enumerable.Range(kvp.Value.Minimum, kvp.Value.Maximum - kvp.Value.Minimum + 1)
select new[] { new KeyValuePair<string, int>(kvp.Key, n) }.ToDictionary(x => x.Key, x => x.Value);
}
};
这会产生以下词典列表:
a=1, b=1, c=1 a=1, b=1, c=2 a=1, b=2, c=1 a=1, b=2, c=2 a=2, b=1, c=1 a=2, b=1, c=2 a=2, b=2, c=1 a=2, b=2, c=2 a=3, b=1, c=1 a=3, b=1, c=2 a=3, b=2, c=1 a=3, b=2, c=2
以下是主要查询的解释:
from kvp in kvps.Take(1)
从kvps
枚举中获取第一个元素(这是可枚举的“头部”)
from n in Enumerable.Range(kvp.Value.Minimum, kvp.Value.Maximum - kvp.Value.Minimum + 1)
从n
到Minimum
生成Maximum
的所有值。
from r in build(kvps.Skip(1))
递归调用列表“尾部”上的build
以生成所有可能的尾部词典
select new[] { new KeyValuePair<string, int>(kvp.Key, n) }.Concat(r).ToDictionary(x => x.Key, x => x.Value);
使用KeyValuePair<string, int>[]
和值Key
创建一个新n
,并在创建新词典时连接尾部(r
)中的每个值。