У вас есть несколько ошибок в вашей функции subsetSum
. Прежде всего, ваша версия имеет ветку, в которой она не возвращает значение. Это могло бы быть легко смягчено с помощью , включившего предупреждения компилятора .
Во-вторых, у вас возникла ошибка в состоянии прерывания. i==n
- недопустимый индекс, поэтому вы перезапустите конец буфера.
Причина, по которой вы получаете один и тот же результат несколько раз, заключается в том, что существует несколько путей к одному и тому же результату. Скорее всего, это связано с отсутствующим оператором возврата.
Исправление для этого заключается в прекращении спуска рекурсии, как только вы найдете совпадение (при его печати). Гарантируется, что вы не найдете дополнительных результатов (если в ваших входах нет записей <= 0
).
bool subSetSum(int* a, int n, int i, int sum, int* r, int k)
{
if (sum == 0) {
printSolution(r, k);
return true;
}
if (i >= n)
return false;
r[k] = a[i];
bool found = subSetSum(a, n, i + 1, sum - a[i], r, k + 1);
found = subSetSum(a, n, i + 1, sum, r, k) || found;
return found;
}
Обратите внимание, что при этом все равно будут найдены повторяющиеся решения для дублированных значений во входном массиве (например, 10
). Вы можете легко добавить проверку, чтобы пропустить дублирующиеся значения во втором рекурсивном вызове в subSetSum
, не передавая i + 1
, но найдя следующий индекс, который не является дубликатом. Поскольку вы уже отсортировали свои входные данные, это можно сделать, увеличив значение i
до тех пор, пока оно не укажет на другое значение.
Также следует отметить, что это довольно unidiomati c C ++. Лучший интерфейс для вашего subsetSum
будет выглядеть так:
template <typename T, typename ConstIterator>
bool subSetSum(ConstIterator begin, ConstIterator end, T sum, std::vector<T>& buf);
template <typename T, typename ConstIterator>
bool subSetSum(ConstIterator begin, ConstIterator end, T sum) {
std::vector<T> buf;
return subSetSum(begin,end,std::move(T),buf);
}