谈谈循环不变量
来源:互联网 发布:itc网络广播终端调试 编辑:程序博客网 时间:2024/06/05 06:22
前两天看到一篇介绍二分原理的帖子,想起了以前写二分法的事情。二分法看似简单,但实际写的时候却发现 +1 -1 的地方很容易弄错。幸好之前看过循环不变量的介绍。
所谓循环不变量,是指在循环过程中保持不变的量。具体取什么样的量呢?显然,pi之类的常量在任何循环中都保持不变,但对分析循环并没有用处。
因此,为便于分析,循环不变量一般会取一个关于循环中的变量 V 的布尔函数 F,在整个循环过程中,F(V)为真,而当循环结束后,(F(V)->R)为真,R是循环的目的。这样,只要证明 F(V) ,即证明了这个循环达到了所要求的目的。
以二分法为例:已知 a[1..n] 是单调递增的数列,求 a 中所有大于或等于 v 的值中,最小的那一个的序号。
如果只是求 a 中等于 v 的值的序号,程序是很容易写出的:
在看下面的分析前,不妨试着先写一个找 a 中大于或等于 v 的最小值的函数,看看循环不变量究竟有没有用。
(说明一下 ":=" 表示“定义为”,"="表示“赋值”,"=="表示“相等”)
在这循环中用到的变量是min,max,首先想到的循环不变量是 F(min,max) := (a[min] <= v <= a[max]),但其中的问题也是显而易见的:循环开始时,v 可能小于 a[1],也可能大于 a[n],而在循环过程中,如果 a[mid-1] < v < a[mid],或者 a[mid] < v < a[mid+1],也会导致 F(min,max) 为假。
解决的方法是在 a 的首尾添加哨兵,即假设 a[0] == -∞, a[n+1] == +∞,循环开始时,min = 0,max = n+1,F(min,max) := (a[min] < v < a[max]) 为真。
循环过程中,当 a[mid] < v 时 min = mid,于是有F(min,max) := (a[min] < v < a[max]) == (a[mid] < v < a[max]) 为真;同样的,当 v < a[mid] 时 max = mid,于是有 F(min,max) := (a[min] < v < a[max]) == (a[min] < v < a[mid]) 为真。
由于 F(min,max) 为真,必然有 min < max (否则,min>=max 且 a[1..n] 升序 -> a[min] >= a[max],与 F(min,max)为真矛盾),因此循环应当在 min == max-1 时结束。此时有:a[max-1] == a[min] < v < a[max],即 a[max] 是 a 中大于或等于 v 的最小值。
程序如下:
循环不变量,并不能用来设计出一个算法,但却可以帮助程序员在写循环时不致因为一些细节问题出错,也可以用于证明循环的正确性,便于阅读者分析循环,增强对代码的信心。
- 谈谈循环不变量
- 循环不变量
- 循环不变量(Loop invariant)
- loop invariant 循环不变量
- Loop Invariant 循环不变量
- 循环不变量的优化
- 从游戏中看循环不变量
- 二分查找变形记:从循环不变量说起
- 不变量解题
- 光照不变量的提取
- 谈谈JAVA中的循环初始化问题
- 谈谈JAVA中的循环初始化问题
- 也来谈谈数组循环移位
- 计算机视觉---4.2---几何不变量
- 谈谈HashMap线程不安全的体现-resize死循环
- 谈谈
- 谈谈~~
- 谈谈
- C# 开发和使用中的23个技巧(常用)
- 面试两个人应届生的经验
- 《Papervision3D Essentials》 翻译 chapter 9
- 跳槽,获取新生
- 我是88年的还在上大学,我是不是选择在大学多蹲几年呢??
- 谈谈循环不变量
- 数据整合基础知识介绍
- vc中error LNK2001:unresolved external symbol _WinMain@16的解决方法
- 生活之美
- 我与Broncho A1的成长
- ASP字符串转换函数用法
- 项目小结之数据库设计
- c++类型转化的比较
- [双语阅读]德国妓院为骑车顾客打折 应对危机