2012-12-10 63 views
1

我想找到一個整數數組的所有子集,所以我的第一個想法是使用大小爲n位的數字的二進制表示,其中1包括和0不'包括。查找與Enumerable.Zip或按位與邏輯的所有子集

例如:

int[] arr = { 3, 4, 5 }; 

要通過數字0至7給了我:

0,0,0 
0,0,1 
0,1,0 
0,1,1 
1,0,0 
...etc 

此映射到:

empty 
5 
4 
4,5 
3 
...etc 

要做到我用Enumerable.Zip映射。代碼是:

public static IEnumerable<byte> ToBinary(this int value, int size) 
{ 
    return ToBinaryStream(value, size).Reverse(); 
} 

private static IEnumerable<byte> ToBinaryStream(int value, int size) 
{ 
    if (value < 0) 
     yield break; 
    do 
    { 
     yield return (byte)(value & 1); 
     --size; 
    } 
    while ((value = value >> 1) > 0 || size > 0); 
} 

int?[] arr = { 1,2,3,4 }; 

List<int[]> subsets = new List<int[]>(); 

for (int i = 0; i < (int)Math.Pow(2, (arr.Length)); i++) 
{ 
    var subset = i.ToBinary(arr.Length).Zip(arr, (value, array) => value == 1 ? array : null) 
     .Where(a => a != null).Cast<int>().ToArray(); 
    subsets.Add(subset); 
} 

似乎工作很好。問題是我如何使用按位AND邏輯來做同樣的事情?

欲1000映射到所述陣列中的第一元件,和1001到第一個和最後等

+0

這是在這裏回答:http://stackoverflow.com/questions/5980810/generate-all-unique-combinations-of-elements-of-a-ienumerableof-t – lontivero

回答

1

要檢查是否與索引i元素x應包括爲多個num

  1. 移位1由i
  2. 按位與用num
  3. 結果如果結果大於0,包括x

下面的代碼:

int[] arr = { 1,2,3,4 }; 

List<int[]> subsets = Enumerable 
       .Range(0, (int)Math.Pow(2, (arr.Length))) 
       .Select(num => arr.Where((x, i) => ((1 << i) & num) > 0).ToArray()) 
       .ToList(); 

它把最低位在num作爲在陣列中的第一個元素,以避免扭轉的東西。順便說一句有趣的想法:)

+0

只是我什麼正在尋找! –