У меня есть упражнение в моем учебнике по алгоритмам, которое просит меня сгенерировать разбиения ряда с целью. Я решил это, но, решая упражнение традиционным способом, я придумал новую идею решения этой проблемы.
Существует традиционный подход:
#include <iostream>
#define MAX_PARTITIONS 100
int count = 1;
void printSolution(int* solution, int size)
{
std::cout << count << "| ";
count++;
for(int i = 0; i < size; i++)
{
std::cout << solution[i] << " ";
}
std::cout << std::endl;
}
void generatePartitions(int* solution, int number, int sum, int partitions)
{
if(sum == number)
{
printSolution(solution, partitions);
return;
}
if(partitions > 1)
{
solution[partitions] = solution[partitions - 1];
}
else
{
solution[partitions] = 0;
}
while(solution[partitions] + sum < number)
{
solution[partitions]++;
sum += solution[partitions];
generatePartitions(solution, number, sum, partitions + 1);
sum -= solution[partitions];
}
}
int main(int argc, char const *argv[])
{
int solution[MAX_PARTITIONS];
generatePartitions(solution, 4, 0, 0);
return 0;
}
В основном, когда количество разделов больше, чем 1
(существует предыдущий раздел) Я назначаю текущему разделу значение предыдущего, в противном случае я назначаю 0
к этому.
Есть новый подход:
#include <iostream>
#define MAX_PARTITIONS 100
int count = 1;
void printSolution(int* solution, int size)
{
std::cout << count << "| ";
count++;
for(int i = 0; i < size; i++)
{
std::cout << solution[i] << " ";
}
std::cout << std::endl;
}
void generatePartitions(int* solution, int number, int sum, int partitions,
int start)
{
if(sum == number)
{
printSolution(solution, partitions);
return;
}
solution[partitions] = start;
while(solution[partitions] + sum < number)
{
solution[partitions]++;
sum += solution[partitions];
generatePartitions(solution, number, sum, partitions + 1,
solution[partitions]);
sum -= solution[partitions];
}
}
int main(int argc, char const *argv[])
{
int solution[MAX_PARTITIONS];
generatePartitions(solution, 4, 0, 0, 0);
return 0;
}
Как видите, функция generatePartitions
принимает новый параметр, start
, Первоначально, значение начала 0
и при каждом рекурсивном вызове start
принимает значение текущего solution[partitions]
, Так что он должен работать так же, как и традиционный метод.
Но это не так, вывод этих программ совершенно другой. Я не могу понять, что не так. Что я делаю неправильно?
Вы забыли переместить индекс solution
массив, когда вы повторяете.
generatePartitions(solution, number, sum, partitions + 1,
solution[partitions]);
будет выглядеть так:
generatePartitions(solution, number, sum, partitions + 1,
solution[partitions-1]);
Coliru ссылка: http://coliru.stacked-crooked.com/a/83b0418e1b1c9bc1
Кроме того, я бы предложил использовать некоторую форму std::pair<int,int>
и что-то вроде двоичного дерева, чтобы сделать это для вас — для меня более логично идти сверху вниз, так как мы пытаемся технически разделить или разделить число на более мелкие; Алгоритм может быть немного сложным, но может быть возможно показать дерево, когда вы закончите с ним.