每个数字组合的递归函数
本文关键字:递归函数 组合 数字 | 更新日期: 2023-09-27 18:37:04
提供一些上下文:我正在开发一个算法问题构建器,最终用户可以在其中输入变量,为其分配范围和规则,在公式中使用它们并实现(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
有没有一个简单的递归函数可以比迭代函数更好地处理这个问题?
感谢您的帮助!
如果我从一个可以表示您的值范围的结构开始,如下所示:
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=1a=1, b=1, c=2a=1, b=2, c=1a=1, b=2, c=2a=2, b=1, c=1a=2, b=1, c=2a=2, b=2, c=1a=2, b=2, c=2a=3, b=1, c=1a=3, b=1, c=2a=3, b=2, c=1a=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)
生成从Minimum
到Maximum
的所有n
值。
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);
创建一个带有Key
和值的新KeyValuePair<string, int>[]
n
,并在创建新字典时连接尾部(r
)中的每个值。