[英]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.