使用分而治之的最大子阵列和

时间:2014-10-19 22:30:09

标签: c++ algorithm iterator divide-and-conquer

使用分割和征服方法here处理一个查找序列的最大连续和的实现。

我的返回值通常不正确。 例如:

{5, 3} returns 5 instead of 8.
{-5, 3} returns 0 instead of 3.
{ 6, -5, 7 } returns 7 instead of 8. 

其他说明:

  • 递减或递增AT第一个或最后一个迭代器抛出一个异常,说我要么在这一点上不能递增,递减或取消引用。我认为GCSMid中存在一个错误,但我无法解决它。
  • 此实现使用随机访问迭代器,表示为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));    
    }
    

1 个答案:

答案 0 :(得分:1)

您的代码有两个问题:

一个。这个循环:

for (RAIter i = center; i > first; i--)

在循环中不包含first。参考算法可以。您不能仅使用>=作为参考算法,因为它不适用于迭代器。要么添加一些额外的代码来检查最后的first,要么更改你的循环,以便它以某种方式包含first(也许一个while循环更适合)。

B中。这些定义:

size_t sum = 0;
size_t leftSum = 0;
size_t rightSum = 0;

不应为size_t,因为size_t是无符号的。这意味着当总和为负时,if(sum > leftSum)之类的检查不再有效,因为负值(下溢)大于正值。

将其更改为int

找到这类错误的最佳方法是通过调试器运行代码。然后,您可以逐步浏览代码的每一行,看看变量值是什么。这样可以很容易地发现负数变成大数正数的事情。