我有一个包含预定义int值的列表。
List<int> values = new List<int>() { 1, 5, 7, 12, 20 };
我想知道某个值是否可以通过我的列表中的值来总结。
public bool canBeSummed(int value)
{
//Can any of the values in values sum up to value?
}
我该如何解决这个问题?
答案 0 :(得分:2)
您必须从列表中获取所有组合,而不是检查sum是否等于提供的值:
创建扩展方法以从值列表中获取组合(这将在以后帮助您)
public static class ExttensionMethods
{
public static IEnumerable<IEnumerable<T>> Combinations<T>(this IEnumerable<T> elements, int k)
{
return k == 0 ? new[] { new T[0] } :
elements.SelectMany((e, i) =>
elements.Skip(i + 1).Combinations(k - 1).Select(c => (new[] { e }).Concat(c)));
}
}
接下来创建方法:
public bool CanBeSummed(int value, int[] values)
{
if (values.Contains(value)) return true;
var smaller = values.Where(x => x <= value);
if (!smaller.Any()) return false; // all values are bigger than value
var count = smaller.Count();
if (count == 1) return false; // Only 1 number and it is not value since values.Contains(value) has to be false
// Check all combinations from items (from 2 to x items where x is number of items in smaller list
return Enumerable.Range(2, count - 1).Any(x => smaller.Combinations(x).Any(c => c.Sum() == value));
}
测试:
public static object[] SumTest =
{
new object[] {6, true, new int[] {1, 5, 7, 12, 20}},
new object[] {37, true, new int[] {1, 5, 7, 12, 20}},
new object[] {9, false, new int[] {1, 5, 7, 12, 20}}
};
[TestCaseSource("SumTest")]
public void Test(int value, bool expectedResult, int[] values)
{
Assert.AreEqual(expectedResult, CanBeSummed(value, values));
}