我试图将下面的Java代码转换为C#。Java代码运行良好,但C#代码<没有返回功率集>没有返回功率集>。我是不是错过了什么?
Java代码
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
List<List<Integer>> subsets = new ArrayList<>();
System.out.println(generateSubsets(
0,
list.stream().mapToInt(i -> i).toArray(),
new ArrayList<Integer>(),
subsets));
}
static List<List<Integer>> generateSubsets(
int index,
int[] nums,
List<Integer> current,
List<List<Integer>> subsets){
subsets.add(new ArrayList<>(current));
for(int i = index; i < nums.length; i++){
current.add(nums[i]);
generateSubsets(i + 1, nums,current, subsets);
current.remove(current.size() - 1);
}
return subsets;
}
C#代码
static List<List<Integer>> generateSubsets(
int index,
int[] nums,
List<Integer> current,
List<List<Integer>> subsets) {
subsets.add(new List(current));
for (int i = index; (i < nums.length); i++) {
current.add(nums[i]);
generateSubsets((i + 1), nums, current, subsets);
current.remove((current.size() - 1));
}
return subsets;
}
预期输出
[[], [1], [1, 2], [1, 2, 3], [1, 3], [2], [2, 3], [3]]
从零开始创建generateSubsets
,然后从Java转换例程,似乎会更容易。我们可以在Linq:的帮助下实现该方法
using System.Linq;
...
private static List<List<T>> generateSubsets<T>(List<T> source) {
return Enumerable
.Range(0, 1 << source.Count)
.Select(index => Enumerable
.Range(0, source.Count)
.Where(i => (index & (1 << i)) != 0)
.Select(i => source[i])
.ToList())
.ToList();
}
代码背后的想法是生成所有掩码[0 .. 2**Count)
,然后根据每个掩码取子集项:
000....000 - empty set (no items)
000....001 - set with 1st item only
000....010 - set with 2nd item only
000....011 - set with 1st and 2nd items
000....100 - set with 3d item only
..........
111....110 - set with all items except 1st one
111....111 - set with all items
演示:
public static void Main(String[] args) {
List<int> list = new List<int>() {
1, 2, 3,
};
var subsets = generateSubsets(list);
Console.Write(string.Join(Environment.NewLine, subsets
.Select(s => $"[{string.Join(", ", s)}]")));
Console.ReadLine();
}
结果:
[]
[1]
[2]
[1, 2]
[3]
[1, 3]
[2, 3]
[1, 2, 3]