我想找到整数数组的所有子集,所以我首先想到的是使用大小为n位的数字的二进制表示,其中1包括0而不包括。
例如:
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 :(得分:1)
要检查数字x
是否应包含索引i
的元素num
:
i
num
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
中的最低位视为数组中的第一个元素,以避免必须反转。顺便提一下有趣的想法:)