Работаем над реализацией поиска наибольшей непрерывной суммы последовательности, используя метод «Разделяй и властвуй», как видно Вот.
Мое возвращаемое значение часто неверно.
Например:
{5, 3} returns 5 instead of 8.
{-5, 3} returns 0 instead of 3.
{ 6, -5, 7 } returns 7 instead of 8.
Другие заметки:
эта реализация использует итераторы с произвольным доступом, обозначенные как RAIter
//function max- finds greatest number given 3 size_ts
size_t max(size_t a, size_t b, size_t c)
{
if (a >= b && a >= c)
{
return a;
}
else if (b >= a && b >= c)
{
return b;
}
else
{
return c;
}
}//function gcsMid
//main algorithm to find subsequence if it spans across the center line
template<typename RAIter>
size_t gcsMid(RAIter first, RAIter center, RAIter last)
{
size_t sum = 0;
size_t leftSum = 0;
size_t rightSum = 0;
//to the left of center
for (RAIter i = center; i > first; i--)
{
sum += *i;
if(sum > leftSum)
{
leftSum = sum;
}
}
//to right of center
sum = 0;
for (RAIter j = (center + 1); j < last; j++)
{
sum += *j;
if (sum > rightSum)
{
rightSum = sum;
}
}
//return the sums from mid
return leftSum + rightSum;
}//main function to call
template<typename RAIter>
int gcs(RAIter first, RAIter last)
{
size_t size = distance(first, last);
//base case is when the subarray only has 1 element. when first == last
if (first == last || size == 1)
{
if (size < 1)
{
return 0;
}
if (*first < 0)
{
return 0;
}
return *first;
}
//middle point
RAIter center = first + (size/2);
//return max of leftsum, rightsum, and midsum
return max(gcs(first, center),
gcs(center + 1, last),
gcsMid(first, center, last));
}
У вас есть две проблемы с вашим кодом:
А. Эта петля:
for (RAIter i = center; i > first; i--)
не включает в себя first
в петле. Эталонный алгоритм делает. Вы не можете просто использовать >=
как эталонный алгоритм делает то, что он не работает для итераторов. Либо добавьте дополнительный бит кода для проверки first
в конце или измените ваш цикл так, чтобы он как-то включал first
(возможно, цикл do while подойдет лучше).
Б. Эти определения:
size_t sum = 0;
size_t leftSum = 0;
size_t rightSum = 0;
не должно быть size_t
как size_t
без знака Это означает, что когда сумма становится отрицательной, чеки, как if(sum > leftSum)
больше не работает, так как отрицательное значение (которое уменьшается) больше, чем положительное значение.
Измените их на int
,
Лучший способ найти ошибки такого рода — запустить код через отладчик. Затем вы можете пройтись по каждой строке вашего кода и посмотреть, каковы значения переменных. Это позволяет легко обнаружить, что отрицательные числа становятся большими положительными числами, как указано выше.