C# 数组和';s子集
我正在寻找一些关于查找数组子集的帮助C# 数组和';s子集,c#,arrays,sum,subset,C#,Arrays,Sum,Subset,我正在寻找一些关于查找数组子集的帮助 int[] array = { 1,2,3,5,8,10,15,23}; 我必须找到数组的所有子集。若子集合元素之和等于数组中的任何数字,那个么我的计数器递增。例如:1+2=3,2+3=5,5+8+10=23,1+2+5=8,2+3+8+10=23 public static void Main(string[] args) { int[] array = { 1, 2, 3, 5, 8, 10, 15, 23 };
int[] array = { 1,2,3,5,8,10,15,23};
我必须找到数组的所有子集。若子集合元素之和等于数组中的任何数字,那个么我的计数器递增。例如:1+2=3,2+3=5,5+8+10=23,1+2+5=8,2+3+8+10=23
public static void Main(string[] args)
{
int[] array = { 1, 2, 3, 5, 8, 10, 15, 23 };
int arrayLength = array.Count();
int sum = 0;
int subsetCount = 0;
for (int i = 0; i < arrayLength; i++)
{
for (int j = i + 1; j < arrayLength; j++)
{
sum = array[i] + array[j];
for (int m = j + 1; m < arrayLength; m++)
{
for (int k = 0; k < arrayLength; k++)
{
if (array[k] == sum)
{
subsetCount++;
}
}
sum = array[i] + array[j] + array[m];
}
}
}
Console.WriteLine(subsetCount);
Console.ReadLine();
}
publicstaticvoidmain(字符串[]args)
{
int[]数组={1,2,3,5,8,10,15,23};
int arrayLength=array.Count();
整数和=0;
int subsetCount=0;
对于(int i=0;i
我对子集的2-元素和3-元素没有意见。但是4级以上我就不知道怎么解决了
任何帮助都将不胜感激您只需要两个循环即可找到所有子集的总和。外循环是子集的起点,内循环是从该起点计算所有子集的和 以第一个索引为起点,子集为
1+2
,1+2+3
,1+2+3+5
,依此类推。因为您只对子集的总和感兴趣,所以您只需将一个项依次添加即可获得子集的总和
然后,对于每个要检查匹配项的总和循环:
int[] array = { 1, 2, 3, 5, 8, 10, 15, 23 };
int subsetCount = 0;
for (int i = 0; i < array.Length; i++) {
int sum = array[i];
for (int j = i + 1; j < array.Length; j++) {
sum += array[j];
for (int k = 0; k < array.Length; k++) {
if (array[k] == sum) {
subsetCount++;
}
}
}
}
Console.WriteLine(subsetCount);
这就给了我们14个不同的子集,这些子集加起来就是集合中的一个项
您可以递归地对子集进行计数,只跟踪子集中项目的总数和数量。您不需要实际的子集,只需要知道总和,并且子集中至少有两个项
集合中的子集是集合其余部分的所有子集加上集合其余部分的子集的第一项组合。例如[1,2,3]
的子集s()
是1、s([2,3])
和s([2,3])
这将为您提供:
public static int CountSubsets(int[] arr, int start, int len, int sum) {
int cnt = 0;
if (start < arr.Length) {
if (len >= 1 && arr.Contains(sum + arr[start])) cnt++;
cnt += CountSubsets(arr, start + 1, len + 1, sum + arr[start]);
cnt += CountSubsets(arr, start + 1, len, sum);
}
return cnt;
}
输出:
14
这对我来说很像家庭作业。因此,我将本着这种精神回答(即,不是编写代码,而是为您指出正确的方向) 首先,不太清楚“子集”是什么意思。您是说数组中的元素连续运行吗?或者你的字面意思是把数组当作一个无序的集合,从中检查每个可能的子集 后者要比前者困难得多。所以我现在假设前者 那么,你似乎真的有两个不同的问题:
- 找到数组的所有子集并对每个子集求和
- 对于给定的和,确定它是否在数组中
HashSet
实例,然后当您想知道和是否在数组中时,只需检查集合
例如:
HashSet<int> setOfValues = new HashSet<int>(array);
HashSet setOfValues=新的HashSet(数组);
然后您可以只写setOfValues.Contains(sum)
来检查变量sum
所持有的值是否包含在数组中
至于第一个问题,在我看来,您实际上只需要两个循环:
- 对子集的第一个元素的索引进行迭代的循环。即,您需要枚举所有子集,首先从以元素0开头的所有子集开始,然后从以元素1开头的所有子集开始,依此类推
- 循环以迭代子集的长度。也就是说,在确定了当前子集组的起始索引之后,现在您希望找到所有实际的子集:第一个子集的长度为1,第二个子集的长度为2,依此类推,直到可能的最大长度(即数组的长度减去当前基于0的起始索引值)
考虑一下另一种可能性——将数组视为无序集——在我看来,一种显而易见的方法(如果是蛮力方法的话)是递归生成子集 在这种方法中,您将再次有一个循环来枚举子集长度,从1开始,一直到原始集合的总长度。然后,给定一个长度,您需要选择所有可能的子集 您可以递归地执行此操作:
- 给定一个集合,迭代当前集合的元素(传递给递归方法)。当前元素是当前子集的新元素
- 如果当前子集的长度正确,则求和并与原始集进行比较
- 否则,从当前集合中删除当前元素并递归
int[] array = {1, 2, 3, 5, 8, 10, 15, 23};
var subsets = new List<IEnumerable<int>>();
int counter = 0;
for (int i = 0; i < array.Length; i++)
{
for (int j = 2; j < array.Length - i; j++)
{
if (array.Contains(array.Skip(i).Take(j).ToList().Sum()))
{
counter++;
}
}
}
Console.WriteLine("Number of subsets:" + counter);
int[]数组={1,2,3,5,8,10,15,23};
变量子集=新列表();
int计数器=0;
for(int i=0;iHashSet<int> setOfValues = new HashSet<int>(array);
int[] array = {1, 2, 3, 5, 8, 10, 15, 23};
var subsets = new List<IEnumerable<int>>();
int counter = 0;
for (int i = 0; i < array.Length; i++)
{
for (int j = 2; j < array.Length - i; j++)
{
if (array.Contains(array.Skip(i).Take(j).ToList().Sum()))
{
counter++;
}
}
}
Console.WriteLine("Number of subsets:" + counter);
Func<IEnumerable<int>, IEnumerable<IEnumerable<int>>> getAllSubsets = null;
getAllSubsets = xs =>
(xs == null || !xs.Any())
? Enumerable.Empty<IEnumerable<int>>()
: xs.Skip(1).Any()
? getAllSubsets(xs.Skip(1))
.SelectMany(ys => new [] { ys, xs.Take(1).Concat(ys) })
: new [] { Enumerable.Empty<int>(), xs.Take(1) };
{ }
{ 1 }
{ 2 }
{ 1, 2 }
{ 3 }
{ 1, 3 }
{ 2, 3 }
{ 1, 2, 3 }
int[] array = { 1,2,3,5,8,10,15,23};
var result =
getAllSubsets(array)
.Where(ss => array.Contains(ss.Sum()))
.Count();