给出以下线性搜索算法(将索引1称为元素数组中第一个元素的索引):
found_idx = nil
for i = 1 to A.length
if A[i] == value
found_idx = i
return found_idx
end-if
end-for
found_idx
我想知道这个循环不变量是否正确: “在for循环的每次迭代开始时,found_idx是数组中以i-1结尾的索引,如果该值存在,则该值存在”
以下是我根据CLRS中的格式提出的关于此循环不变量的非正式解释:
i
的每个值都会检查A[i]
,然后然后 i
增加,意味着在每次新迭代之前已经检查了所有直到i-1
的元素。i > A.length
时终止,这意味着已经检查了包括A.length
在内的所有元素。我主要关注的是引用以i-1
结尾的索引感觉不正确,因为循环以i
为1开始,这是数组的第一个元素。换句话说,引用阵列的子阵列感觉是错误的,其中子阵列以小于阵列的起始索引的索引结束,对于该阵列,子阵列首先应该是子阵列。这似乎意味着上面给出的循环不变量在循环的第一次迭代之前实际上是假的。
思想?
答案 0 :(得分:1)
由于循环提前终止,其不变量如下:
found_idx = nil && ∀k<i : A[k] ≠ value
&&
之后的部分表示&#34; A
以下索引的所有i
元素都不等于value
&#34;
found_idx
保留在nil
,或提前终止循环i
到达A.length
循环的后置条件为found_idx = nil && ∀k<A.length : A[k] ≠ value
,这意味着value
不属于A
个元素。这也意味着您可以通过重写循环来消除found_idx
,如下所示:
for i = 1 to A.length
if A[i] == value
return i
end-if
end-for
return nil