[英]Recursively determine whether elements in array can sum to target - C++
I am doing practice with recursion and trying small problems. 我正在练习递归和尝试小问题。 One of the functions I am trying to design comboSum
takes in an array of integers, its size, and a target value. 我试图设计comboSum
的一个函数是一个整数数组,它的大小和一个目标值。 It returns true if a combination of any of the elements (can only use each element once) adds to the target value. 如果任何元素的组合(只能使用每个元素一次)添加到目标值,则返回true。 This is my implementation so far. 到目前为止,这是我的实现。
// Expected Behaviors
// comboSum([1, 2, 3], 3, 0) => false
// comboSum([2, 4, 8], 3, 12) => true
// comboSum([2, 4, 8], 3, 11) => false
// comboSum([], 0, 0) => true
bool comboSum(const int a[], int size, int target)
{
if (target == 0)
return true; // if we have decremented target to zero
if (target != 0 && size == 0)
return false; // if we havent hit target to zero and we have no more elements
size--;
return (comboSum(a, size, target) || comboSum(a, size, target - a[size]));
// OR logic ensures that even if just one sum exists, this returns true
}
My algorithm works except for the case of an array with all non-zero values and the target being zero. 我的算法工作,除了具有所有非零值且目标为零的数组的情况。 The function immediately returns true without checking for a valid summation. 该函数立即返回true而不检查有效求和。
// comboSum({1, 2, 3}, 3, 0) returns true when this should be false
What are some possible ways to correct this issue? 有哪些方法可以解决这个问题?
Edit: I cannot change the parameters or call any additional helper functions. 编辑:我无法更改参数或调用任何其他辅助函数。 The function header must remain as is and I must solve the problem recursively (no use of for or while loops or STL algorithms) 函数头必须保持原样,我必须递归地解决问题(不使用for或while循环或STL算法)
A simple solution is to keep the size
parameter fixed and have another parameter that indicates the current position of the recursion. 一个简单的解决方案是保持size
参数固定,并有另一个参数指示递归的当前位置。
bool comboSum(const int *a, int size, int pos, int target) {
if (target == 0)
return pos < size || size == 0; // true if pos has moved or if the array is empty
else if (pos == 0)
return false;
pos--;
return comboSum(a, size, pos, target) || comboSum(a, size, pos, target - a[pos]);
}
This solution handles your test cases correctly, but we have to pass the pos
argument after the size
argument. 此解决方案正确处理您的测试用例,但我们必须在size
参数后传递pos
参数。 Both arguments should start with the same value: 两个参数都应以相同的值开头:
// comboSum([1, 2, 3], 3, 3, 0) => false
// comboSum([2, 4, 8], 3, 3, 12) => true
// comboSum([2, 4, 8], 3, 3, 11) => false
// comboSum([], 0, 0, 0) => true
Since this question is tagged as C++, it would be a good idea to use a class that gives us more flexibility than C arrays. 由于这个问题被标记为C ++,因此使用一个比C数组更灵活的类是个好主意。 For example, we could use a std::vector
. 例如,我们可以使用std::vector
。 If that's the case, then we don't need an extra parameter for the size of the list: 如果是这种情况,那么我们不需要额外的参数来表示列表的大小:
#include <vector>
bool comboSum(std::vector<int>& v, size_t pos, int target)
{
if (target == 0) {
return pos < v.size() || v.size() == 0;
} else if (pos == 0) {
return false;
}
pos--;
return comboSum(v, pos, target) || comboSum(v, size, target - v[pos]);
}
If you want to keep everything you have as-is, try adding a variable to count the number of recursions. 如果要保留原样,请尝试添加变量来计算递归次数。
bool comboSum(const int a[], int size, int target, int count = 0)
{
if (target == 0 && size == 0 && count == 0)
return false;
else if (target == 0)
return true;
else if (target != 0 && size == 0)
return false;
size--;
return (comboSum(a, size, target) || comboSum(a, size, target - a[size]));
};
Please note that there are definitely better ways to do this, but as a learning exercise it doesn't hurt to give this a go! 请注意,肯定有更好的方法可以做到这一点,但作为一个学习练习,这样做是不会有害的!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.