[英]Loop Through Every Possible Combination of an Array
我通过在C#依赖于规模,而不是为了一个阵列的每个组合试图循环。 例如: var states = ["NJ", "AK", "NY"];
一些组合可能是:
states = [];
states = ["NJ"];
states = ["NJ","NY"];
states = ["NY"];
states = ["NJ", "NY", "AK"];
依此类推...在我的情况下, states = ["NJ","NY"]
和states = ["NY","NJ"]
也是同一件事,因为顺序无关紧要。
有没有人对最有效的方式任何想法做到这一点?
以下两种方法的组合应该可以实现您想要的。 这个想法是,如果项数为n,则子集数为2 ^ n。 并且,如果您从0迭代到2 ^ n-1并查看二进制数,则每个项目都有一个数字,如果数字为1,则包含该项目,如果为0,则不包含该项目。 我在这里使用BigInteger
,因为int
仅适用于少于32个项目的集合,而long
仅适用于少于64个项目的集合。
public static IEnumerable<IEnumerable<T>> PowerSets<T>(this IList<T> set)
{
var totalSets = BigInteger.Pow(2, set.Count);
for (BigInteger i = 0; i < totalSets; i++)
{
yield return set.SubSet(i);
}
}
public static IEnumerable<T> SubSet<T>(this IList<T> set, BigInteger n)
{
for (int i = 0; i < set.Count && n > 0; i++)
{
if ((n & 1) == 1)
{
yield return set[i];
}
n = n >> 1;
}
}
有了下面的代码
var states = new[] { "NJ", "AK", "NY" };
foreach (var subset in states.PowerSets())
{
Console.WriteLine("[" + string.Join(",", subset.Select(s => "'" + s + "'")) + "]");
}
会给你这个输出。
[]
['NJ']
['AK']
['NJ','AK']
['NY']
['NJ','NY']
['AK','NY']
['NJ','AK','NY']
您可以使用回溯,在每次迭代中,您要么(1)取得索引i中的项目,要么(2)不取得索引i中的项目。
此问题的伪代码:
主要代码:
states
长度的布尔数组(例如,命名为picked
) 回溯功能:
states
数组,其长度,当前索引和布尔数组 states
打印匹配的字符串 picked[i]
设置为true
并使用下一个索引调用回溯功能 picked[i]
设置为false
并使用下一个索引调用回溯功能
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.