在《数据结构和算法分析——C语言描述》一书中,有一段关于求最大子列和的算法比较,其中提到了用联机算法实现。
我们首先说一说联机算法,百度词条给出的定义是这样的
联机算法是在任意时刻算法对要操作的数据只读入(扫描)一次,一旦被读入并处理,它就不需要在被记忆了。
而在此处理过程中算法能对它已经读入的数据立即给出相应子序列问题的正确答案。
还有对这种算法的无比崇拜
“该算法仅需要常量空间并以线性时间运行,因此联机算法几乎是完美的算法。”
当然还是有缺点的
“不宜设计,正确性不易观察,同时附加保留信息较少”
我们今天把这些摆出来,并不深究这些。我们今天来谈一下联机算法解决最大子序列的正确性
先摆出代码,C语言版本的
int MaxSubsequenceSum(const int A[],int N)
{
int ThisSum,MaxSum,j;
ThisSum = MaxSum = 0;
for(j=0;j<N;j++)
{ThisSum+=A[i];
if (ThisSum>MaxSum)
MaxSum=ThisSum;
else if (ThisSum<0)
ThisSum=0;
}
return MaxSum;
}
理解的关键就在于:
如果A[i]为负值且为起点,则我们可以取A[i+1]为起点,此时离目标更进。如果以一个 和为负数 的子列的起点,则我们可以舍去这个子列,此时也更进了目标一步。
但是不知道是书上没写清还是我没注意到,有一种情况是客观存在的,那就是所有的元素均为负值,此时根据这个联机算法我们得到的是0,但实际上结果应该是最大的元素。
那我们不妨加上一段代码,如果MaxSum为0,找出整个序列中的最大值即可
其实上了大学才发现,没有什么东西是好学的,无论是数学还是计算机,有点难受。
无论怎么样还是得硬着头皮学下去啊,以后真的会感谢曾经努力的自己,真的。
作者:板蓝根的板蓝