《趣题学算法》—第0章0.4节算法的正确性

0.4 算法的正确性
解决一个计算问题的算法是正确的,指的是对问题中任意合法的输入均应得到对应的正确输出。大多数情况下,问题的合法输入无法穷尽,当然就无法穷尽输出是否正确的验证。即使合法输入是有限的,穷尽所有输出正确的验证,在实践中也许是得不偿失的。但是,无论如何,我们需要保证设计出来的算法的正确性。否则,算法设计就是去了它的应用意义。因此,对设计出来的算法在提交应用之前,应当说明它的正确性。这就需要借助我们对问题的认识与理解,利用数学、科学及逻辑推理来证实算法是正确的。例如,对于解决“计算逆序数”问题的算法0-1,其正确性可以表述为如下命题:

当第3~7行的for循环结束时,count已记录下了序列A[1..N]中的逆序数。

如果我们能说明上述命题是真的,那就说明了算法0-1是正确的。由于数组A[1..N]的长度N是任意正整数,所以这是一个与正整数相关的命题。数学中要证明一个与正整数相关的命题有一个有力的工具——数学归纳法。下面我们对本命题中的N进行归纳。

当N=1时第3~7行的for循环重复0次。count保持初始值0,这与A[1..N]=A[1]没有任何逆序相符,结论显然为真。

设N>1且可用算法计算出A[1..N−1]的逆序数count。在此假设下,我们来证明对A[1..N]利用算法0-1也能得到正确的逆序数count。

考虑算法中第3~7行的for循环在j=N时的第一次重复的操作:第4~6行内嵌的for循环从i=1开始到j−1为止,逐一检测是否A[i]>A[j]。若是,意味着找到一个关于A[N]的逆序,第6行count自增1。当此循环结束时count中累积了关于A[N]的逆序数。由于N>1,故第3~6行的外围for循环必定会继续对A[1..N−1]做同样的操作。根据归纳假设,我们知道第3~6行的for循环接下来的重复操作能将A[1..N−1]中个元素的逆序数累加到count中。所以第3~6行for循环结束时,count已记录下了序列A[1..N]中的逆序数。

这样,我们就从逻辑上证明了算法0-1能正确地解决“计算逆序数”问题的一个案例,即算法0-1是正确的。

应当指出,解决一个计算问题时,算法不必唯一。数据的组织方式、解题思路的不同,会导致不同的算法。

例如,将计数器count设置为全局变量,并初始化为0。解决“计算逆序数”问题一个案例的算法还可以表示为如下的形式。

GET-THE-INVERSION(A, N)            ▷A[1..N]表示一个序列
1 if N<2
2     then return
3 for i←1 to N-1
4   do if A[i]>A[N]                ▷检测到一个逆序
5     then count←count+1           ▷累加到计数器
6 GET-THE-INVERSION(A, N-1)

算法0-2 解决“计算逆序数”问题一个案例的递归算法伪代码过程

这是一个“递归”算法,它在定义的内部(第6行)进行了一次自我调用。受上述算法0-1正确性命题证明的启发,这个算法的思想是基于先计算出A[1..N-1]中关于A[N]的逆序数count,然后将问题归结为计算A[1..N-1]的逆序数的子问题。用相同的方法解决子问题(递归调用自身,注意表示A的长度的第2个参数变成N-1)把子问题的解与count合并就可得到原问题的解。其实,算法0-2与算法0-1仅仅是表达形式不同,本质上等价的:后者用末尾递归(第6行递归调用自身)隐式地替代算法0-1中第3~6行的外层for循环。所以,算法0-2也是正确的。

时间: 2024-09-28 09:49:47

《趣题学算法》—第0章0.4节算法的正确性的相关文章

《趣题学算法》—第0章0.1节App程序与算法

第0章 从这里开始趣题学算法0.1 App程序与算法 0.2 计算问题 0.3 算法的伪代码描述 0.4 算法的正确性 0.5 算法分析 0.6 算法运行时间的渐近表示 0.7 算法的程序实现 0.8 从这里开始 0.1 App程序与算法信息时代,人们时刻都在利用各种App解决生活.工作中的问题,或获取各种服务.早晨,手机里设定的闹钟铃声(或你喜欢的音乐)将你唤醒.来到餐厅,你用手中的IC卡到取餐处的刷卡机上支付美味早餐的费用.上班途中,打开手机上的音乐播放器,用美妙的乐声,打发掉挤在公交车上的

《趣题学算法》—第1章1.1节累积计数法

第1章 计数问题 趣题学算法 1.1 累积计数法 1.2 简单的数学计算 1.3 加法原理和乘法原理 1.4 图的性质 1.5 置换与轮换 人类的智力启蒙发端于计数.原始人在狩猎过程中为计数猎获物,手指.结绳等都是曾经使用过的计数工具.今天,我们所面对.思考的问题更加复杂.庞大,计数的任务需要强大的计算机来帮助我们完成.事实上,很多计算问题本身就是计数问题. 1.1 累积计数法 这样的问题在实际中往往要通过几个步骤来解决,每个步骤都会产生部分数据,问题的目标是计算出所有步骤产生数据的总和.对这样

《趣题学算法》目录—导读

版权 趣题学算法 • 著 徐子珊 责任编辑 张 涛 • 人民邮电出版社出版发行 北京市丰台区成寿寺路11号 邮编 100164 电子邮件 315@ptpress.com.cn 网址 http://www.ptpress.com.cn • 读者服务热线:(010)81055410 反盗版热线:(010)81055315 内容提要 趣题学算法 本书共分10章.第0章讲解了算法的概念及体例说明.第1-7章分别就计数问题.信息查找问题.组合优化问题.图中搜索问题和数论问题展开,讨论了算法的构思和设计,详

《趣题学算法》—第0章0.3节算法的伪代码描述

0.3 算法的伪代码描述 上一节最后一段使用自然语言(汉语)描述了解决"计算逆序数"问题的算法.即如何将输入数据转换为输出数据的过程.在需要解决的问题很简单的情况下(例如"计算逆序数"问题),用自然语言描述解决这个问题的算法是不错的选择.但是,自然语言有一个重要特色--语义二岐性.语义二岐性在文学艺术方面有着非凡的作用:正话反说.双关语--.由此引起的误会.感情冲突--带给我们多少故事.小说.戏剧--.但是,在算法描述方面,语义二岐性却是我们必须避免的.因为,如果对

《趣题学算法》—第0章0.6节算法运行时间的渐近表示

0.6 算法运行时间的渐近表示由于计算机技术不断地扩张其应用领域,所要解决的问题输入规模也越来越大,所以对固定的n来计算T(n)的意义并不大,我们更倾向于评估当n→∞时T(n)趋于无穷大的快慢,并以此来分析算法的时间复杂性.我们往往用几个定义在自然数集N上的正值函数Ỹ(n):幂函数nk(k为正整数),对数幂函数lgkn(k为正整数,底数为2)和指数函数an(a为大于1的常数)作为"标准",研究极限 lim_{ntoinfty}frac{T(n)=lambda }{widetilde{Y

《趣题学算法》—第0章0.5节算法分析

0.5 算法分析解决同一问题的不同算法所消耗的计算机系统的时间(占用处理器的时间)和空间(占用内部存储器空间)资源量可能有所不同.算法运行所需要的资源量称为算法的复杂性.一般来说,解决同一问题的算法,需要的资源量越少,我们认为越优秀.计算算法运行所需资源量的过程称为算法复杂性分析,简称为算法分析.理论上,算法分析既要计算算法的时间复杂性,也要计算它的空间复杂性.然而,算法的运行时间都是消耗在已存储的数据处理上的,从这个意义上说,算法的空间复杂性不会超过时间复杂性.出于这个原因,人们多关注于算法的

《趣题学算法》—第1章1.2节简单的数学计算

1.2 简单的数学计算以上那样利用循环重复将部分数据简单地累加,可以解决很多计数问题.然而,如果计数问题可以通过数学计算直接得出结果,往往可以大大改善算法的时间效率,请看下列问题. 问题1-5 小小度刷礼品图片 7 问题描述 一年一度的百度之星大赛又开始了,这次参赛人数创下了吉尼斯世界纪录.于是,百度之星决定奖励一部分人:所有资格赛提交ID以x结尾的参赛选手将得到精美礼品一份. 小小度同学非常想得到这份礼品,于是他就连续提交了很多次,提交的ID从a连续到b.他想知道能得到多少份礼品,你能帮帮他吗

《计算机科学概论(第12版)》—第0章0.4节算法

0.4.1 算法数据存储容量有限,程序设计过程复杂耗时,这些限制了早期计算机器所能处理的算法的复杂性.如今,随着这些局限性的消除,机器能完成的任务越来越大.越来越复杂.人们试图用算法表达这些任务,但单凭人类的智力无法做到,于是,越来越多的研究工作转向了算法和程序设计过程的研究. 正是在这种背景下,数学家的理论研究开始有了回报.由于哥德尔不完备性定理,数学家已经在研究有关算法过程的问题了,而这正是先进技术目前面临的问题.由此,孕育出了被称作计算机科学的这门学科. 如今,计算机科学已经奠定了它算法科

《趣题学算法》—第0章0.8节从这里开始

0.8 从这里开始作为本书讨论的起点,本章通过解决一个典型的计算问题"计算逆序数",明确了诸如算法.伪代码.算法分析.C++程序等概念.术语或名称.通过讨论问题"移动电话"给出了本书每个问题讨论的体例:描述问题--理解问题--设计算法--分析算法的效率. 如果你是一位编程初学者,在看了这两个例子后是否会有这样的问题:怎么会想到这样解这些问题?其实,这和你在学校里学习数学时解应用题很相像.首先,看看题目是归类于代数.几何还是微积分?如果是代数题,再看是用解方程方法还是

《趣题学算法》—第0章0.2节计算问题

0.2 计算问题上面已经说到什么是计算问题,下面就来看一个有趣的计算问题. 问题描述这个学期Amy开始学习一门重要课程--线性代数.学到行列式的时候,每次遇到对给定的序列计算其逆序数,她都觉得是个很闹心的事.所以,她央求她的好朋友Ray为她写一段程序,用来解决这样的问题.作为回报,她答应在周末舞会上让Ray成为她的伦巴舞舞伴.所谓序列A的逆序数,指的是序列中满足iA[j]的所有二元组的个数.输入输入文件包含若干个测试案例.每个案例的第一行仅含一个表示序列中元素个数的整数N(1leqslantNl