我需要弄清楚这段代码的不变量是什么。我认为可能存在多个不变量,但我并不真正理解这个主题,我发现的在线资源仍然没有真正帮助。我为二进制搜索所做的代码是:
public class BinarySearchSqrt {
/** Integer square root
* Calculates the integer part of the square root
* of n, i.e. integer s such that
* s*s <= n and (s+1)*(s+1) > n
* requires n >= 0
*/
private static int iSqrt(int n) {
int l = 0;
int r = n;
int m = ((l + r + 1) / 2);
/* loop invariant
* :
* :
*/
while (Math.abs(l - m) > 0) {
m = ((l + r + 1) / 2);
if ((m + 1) * (m + 1) > n) {
r = m - 1;
} else if ((m * m) < n) {
l = m + 1;
}
}
return m;
}
public static void main(String[] args) {
System.out.println(iSqrt(15));
System.out.println(iSqrt(16));
}
}
此代码使用二进制搜索来查找整数的平方根,但如果它不是平方数,则应返回小于整数的最接近的平方数的平方根。
代码可以工作,但我只是点确实得到了什么作为不变量,以及它如何显示返回的正确值。任何线索/解释都会很棒,谢谢。
答案 0 :(得分:0)
好的,所以这个答案差不多晚了半年,但是这里有:
循环不变量只是在循环的每次迭代之前(和之后)保存的东西。所以在这里,我们需要找到一个条件,每当代码位于标有箭头的地方时有效:
while (Math.abs(l - m) > 0) { // <-------------
m = ((l + r + 1) / 2);
if ((m + 1) * (m + 1) > n) {
r = m - 1;
} else if ((m * m) < n) {
l = m + 1;
}
}
所以在这里,在每次迭代中,你要么更新了r,以便新r更靠近最小的整数&lt; = sqrt(n),通过减少它,或者你更新l,这样新的l就更接近了到最小整数&lt; = sqrt(n),但通过增加它。所以循环不变量就是:
l&lt; = floor(sqrt(n))&lt; = r