簡體   English   中英

遍歷數組的所有可能組合

[英]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
  • 調用索引為0的回溯方法(第一項)

回溯功能:

  • 接收states數組,其長度,當前索引和布爾數組
  • 暫停條件-如果當前索引等於長度,則只需要遍歷bool數組,對於每個為true的項目,從states打印匹配的字符串
  • 實際回溯:
    • picked[i]設置為true並使用下一個索引調用回溯功能
    • picked[i]設置為false並使用下一個索引調用回溯功能

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM