![](/img/trans.png)
[英]How to prove the the correctness of recursive “search” algorithm in the code?
[英]How can I prove algorithm correctness?
我在 Java 中的這個練習有問題,我不明白如何在 Java 中證明這個 sum 方法
這是我做的:
P(0) : If r=0 and i=0 => r=0+a[0]
p(i+1) : r'= r + a[i] and i'=i+1
r'=r + a[i] + a[i+1]
public static int sum(int[] a) {
int r = 0;
int i = 0;
while (i < a.length) {
r = r + a[i];
i = i + 1;
}
return r;
}
循環不變量應該表示r
等於a
從索引0
到索引i
的元素之和,不包括在內。 即r = Sum(k<i: a[k])
。
然后我們可以注釋
int r = 0;
int i = 0;
/* r = Sum(k<i: a[k]) */
while (i < a.length) {
r = r + a[i];
/* r = Sum(k<i: a[k]) + a[i] = Sum(k<i+1: a[k]) */
i = i + 1;
/* r = Sum(k<i: a[k]) */
}
/* r = Sum(k<=a.length: a[k]) */
證明的關鍵是
Sum(k<i: a[k]) + a[i] = Sum(k<i+1: a[k])
表示總和是遞增獲得的。
最簡單的方法是定義一組輸入及其預期輸出。 如果這是用於練習,您可能會獲得這些值,或者您可能需要手動計算其中的一些值。 然后我將使用這些已知輸入編寫單元測試,以查看每個輸出是否與預期值匹配。 如果您發現它們不匹配的地方,請仔細檢查您的算法和預期值。 並排完成每個步驟並找出哪個是錯誤的(或者兩者是否都錯誤)。
另一種選擇是用另一種語言編寫相同的算法; 理想情況下,您不能復制粘貼算法的實現以防止共享常見錯誤。 然后使用大量輸入運行兩者。 如果兩個實現對每個輸入都有匹配的結果,您就可以更有把握地認為兩者都是正確的。
第三種選擇是找到一組不變量,即在算法的各個階段可證明為真的事物。 然后在所有那些表明不變量成立的點上編寫測試(或只是拋出assert
語句)。 for every iteration of the "i" loop, r' >= r
之類for every iteration of the "i" loop, r' >= r
事情。 然后針對大范圍的輸入運行它,如果這些斷言中的任何一個失敗,您可以開始深入研究並找出您忘記在算法中處理的邊緣情況(例如,如果輸入為空怎么辦?我如何處理否定數字?等)
證明您的算法具有預期響應的可能性之一是用單元測試覆蓋它。
@Test
public void sumWorksFineWithNaturalValues() {
int[] input = {1, 2, 3, 4};
int expectedResponse = 10;
assertThat(sum(input)).isEqualTo(expectedResponse);
}
@Test
public void sumCanHandleNegativeValues() {
int[] input = {0, 1, -2, -3, 4};
int expectedResponse = 0;
assertThat(sum(input)).isEqualTo(expectedResponse);
}
@Test
public void sumCanHandleEmptyArray() {
int[] input = {};
int expectedResponse = 0;
assertThat(sum(input)).isEqualTo(expectedResponse);
}
我已經將assertj庫用於 Java 測試
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.