2010-11-13 98 views
-1

我有一個字符串「ABCDE」 的ArrayList我想的方法與給定的ArrayList的所有可能的組合,以返回另一個數組列表:在C#(如AB,AC,AD ...)如何獲得一個數組列表的所有組合?

有誰知道一個簡單的方法?

NB:長度爲2的所有可能的組合,如果長度是可變的,效果會更好(可以更改)

+0

你指的是長度= 2的所有組合? – 2010-11-13 21:55:11

+0

是的,遺憾忘記提到 – Mona 2010-11-13 21:55:48

+0

所有可能的長度組合2 – Mona 2010-11-13 21:56:39

回答

9

修飾您的評論需要長度爲兩個的組合:應對

string s = "abcde"; 
var combinations = from c in s 
        from d in s.Remove(s.IndexOf(c), 1) 
        select new string(new[] { c, d }); 
foreach (var combination in combinations) { 
    Console.WriteLine(combination); 
} 

您編輯任何長度:

static IEnumerable<string> GetCombinations(string s, int length) { 
    Guard.Against<ArgumentNullException>(s == null); 
    if (length > s.Length || length == 0) { 
     return new[] { String.Empty }; 
    if (length == 1) { 
     return s.Select(c => new string(new[] { c })); 
    } 
    return from c in s 
      from combination in GetCombinations(
       s.Remove(s.IndexOf(c), 1), 
       length - 1 
      ) 
      select c + combination; 
} 

用法:

string s = "abcde"; 
var combinations = GetCombinations(s, 3); 
Console.WriteLine(String.Join(", ", combinations)); 

輸出:

abc, abd, abe, acb, acd, ace, adb, adc, ade, aeb, aec, aed, bac, bad, bae, bca, 
bcd, bce, bda, bdc, bde, bea, bec, bed, cab, cad, cae, cba, cbd, cbe, cda, cdb, 
cde, cea, ceb, ced, dab, dac, dae, dba, dbc, dbe, dca, dcb, dce, dea, deb, dec, 
eab, eac, ead, eba, ebc, ebd, eca, ecb, ecd, eda, edb, edc 
+0

你也應該做var retComb = GetCombinations(s,2).Distinct()。其中​​(p => p [0]> = p [p.Length]);刪除多餘的項目,以及項目的反向,例如'aabd'測試你的方法 – 2010-11-14 10:25:42

5

這是我能返回T類型的所有組合的通用功能:

static IEnumerable<IEnumerable<T>> GetCombinations<T>(IEnumerable<T> list, int length) 
{ 
    if (length == 1) return list.Select(t => new T[] { t }); 

    return GetCombinations(list, length - 1) 
     .SelectMany(t => list, (t1, t2) => t1.Concat(new T[] { t2 })); 
} 

用法:

Console.WriteLine(
    string.Join(", ", 
     GetCombinations("abcde".ToCharArray(), 2).Select(list => string.Join("", list)) 
    ) 
); 

輸出:

aa, ab, ac, ad, ae, ba, bb, bc, bd, be, ca, cb, cc, cd, ce, da, db, dc, dd, de, ea, eb, ec, ed, ee 

已更新 對於其他情況,請參閱我的回答here。排列和k-組合等中數字陣列

+0

這是重複而不是組合的置換。 http://www.mathsisfun.com/combinatorics/combinations-permutations.html – 2014-02-26 08:33:57

+0

@HalilKaskavalci,請查看[我的另一個答案](http://stackoverflow.com/a/10629938/1251423)瞭解更多選項。 – Pengyang 2014-03-13 07:36:29

+0

現在看起來好多了。 – 2014-03-13 12:35:20

-1

組合通過僅使用陣列和遞歸:

static int n = 4; 
    int[] baseArr = { 1, 2, 3, 4 }; 
    int[] LockNums; 

    static void Main(string[] args) 
    { 
     int len = baseArr.Length; 
     LockNums = new int[n]; 

     for (int i = 0; i < n; i++) 
     { 
      int num = baseArr[i]; 
      DoCombinations(num, baseArr, len); 
      //for more than 4 numbers the print screen is too long if we need to check the result next line will help 
      //Console.ReadLine(); 

     } 
    } 

    private void DoCombinations(int lockNum, int[] arr, int arrLen)   
    { 
     int n1 = arr.Length; 
     // next line shows the difference in length between the previous and its previous array 
     int point = arrLen - n1; 
     LockNums[n - arr.Length] = lockNum; 

     int[] tempArr = new int[arr.Length - 1]; 
     FillTempArr(lockNum, arr, tempArr); 

     //next condition will print the last number from the current combination 
     if (arr.Length == 1) 
     { 
      Console.Write(" {0}", lockNum); 
      Console.WriteLine(); 
     } 

     for (int i = 0; i < tempArr.Length; i++) 
     { 
      if ((point == 1) && (i != 0)) 
      { 
       //without this code the program will fail to print the leading number of the next combination 
       //and 'point' is the exact moment when this code has to be executed 
       PrintFirstNums(baseArr.Length - n1); 
      } 
      Console.Write(" {0}", lockNum); 
      int num1 = tempArr[i]; 
      DoCombinations(num1, tempArr, n1); 
     } 
    } 

    private void PrintFirstNums(int missNums) 
    { 
     for (int i = 0; i < missNums; i++) 
     { 
      Console.Write(" {0}", LockNums[i]); 
     } 
    } 

    private void FillTempArr(int lockN, int[] arr, int[] tempArr) 
    { 
     int idx = 0; 
     foreach (int number in arr) 
     { 
      if (number != lockN) 
      { 
       tempArr[idx++] = number; 
      } 
     } 
    } 

    private void PrintResult(int[] arr) 
    { 
     foreach (int num in arr) 
     { 
      Console.Write(" {0}", num); 
     } 
    } 
+0

你好,這是我對數字組合的解決方案。該解決方案只使用數組。我正在做這篇文章,因爲我沒有遇到任何地方的數組解決方案。代碼設置爲快速演示,否則它應該適用於任何數組長度。 – 2017-10-29 10:55:10

相關問題