我想从价格表中获取一个列表,其中值的总和等于我想要的值。 让我用例子来解释。
List<int> prices= new List{ 1, 2, 3, 4, 5 };
List<int> filteredList = GetSumList(4); // get list where the sum equals to 4, 1-3 or just 4. it doesn't matter which one.
如何编写GetSumList(int sum)
函数。
答案 0 :(得分:1)
如果请求的总和不会那么大;并且所有项目都是正面的(允许为零),并且您不太关心内存,您可以使用以下方法:
public static IEnumerable<int> GetSumList(this IEnumerable<int> values, int sum) {
List<int>[] sets = new List<int>[sum+1];
sets[0] = new List<int>();
foreach(int xi in values) { //O(N*sum*N) with N the number of items
List<int> f0, f1, f2;
for(int i = sum-xi; i >= 0; i--) { //O(N*sum)
f0 = sets[i];
f1 = sets[i+xi];
if(f0 != null && (f1 == null || f0.Count < f1.Count-1)) {
f2 = new List<int>(f0);//make clone, O(N)
f2.Add(xi);
sets[i+xi] = f2;
}
}
}
return sets[sum];
}
(如果不存在这样的总和,则返回null
;此算法还将返回最小子集(如果有)。
该算法使用动态编程并考虑集列表。每个都有一个不同的总和。如果在计算临时值时使用链接列表而不是List<int>
,则可以更快地执行此操作,因为这允许(共享)克隆和插入头部中的O(1 )。
演示(使用csharp
交互式shell):
csharp> List<int> prices= new List<int>(new int[] { 1, 2, 3, 4, 5 });
csharp> prices.GetSumList(4);
{ 4 }
csharp> prices.GetSumList(6);
{ 2, 4 }
csharp> prices.GetSumList(7);
{ 3, 4 }
csharp> prices.GetSumList(8);
{ 3, 5 }
csharp> prices.GetSumList(9);
{ 4, 5 }
csharp> prices.GetSumList(10);
{ 2, 3, 5 }
csharp> prices.GetSumList(11);
{ 2, 4, 5 }
csharp> prices.GetSumList(12);
{ 3, 4, 5 }
csharp> prices.GetSumList(13);
{ 1, 3, 4, 5 }
csharp> prices.GetSumList(14);
{ 2, 3, 4, 5 }
csharp> prices.GetSumList(15);
{ 1, 2, 3, 4, 5 }
csharp> prices.GetSumList(16);
null
答案 1 :(得分:0)
如果你有列表列表,你可以做一个非常简单的LINQ扩展方法。
using System;
using System.Linq;
using System.Collections;
using System.Collections.Generic;
public class Test
{
public static void Main()
{
var lists = new List<List<int>>
{
new List<int> { 1, 2, 3 }, // 6
new List<int> { 3 }, // 3
new List<int> { 3, 3 }, // 6
new List<int> { 1, 2 }, // 3
new List<int> { 6 } // 6
};
Console.WriteLine(lists.GetSumList(6).Count); // 3
}
}
public static class ListHelpers
{
public static List<List<int>> GetSumList(this List<List<int>> list, int sum)
{
return list.Where(x => x.Sum() == sum).ToList();
}
}