我正试图在java中找到更多关于契约含义的内容。
以下是java中两个合同的示例:
*/
* @pre arr != null
* @pre occurrences(4,arr) == occurrences(5, arr)
* @pre arr[arr.length – 1] != 4
* @pre forall 0 <= i < arr.length-2, arr[i] == 4 ==> arr[i+1] != 4
* @post forall 0 <= i < arr.length-1, $prev(arr[i]) == arr[i]
* @post $ret != arr
* @post permutation(arr, $ret)
* @post forall 0 <= i < arr.length-1, arr[i] == 4 ==> $ret[i] == 4
* @post forall 0 <= i < $ret.length-2, $ret[i] == 4 ==> $ret[i+1] == 5
/
第二个:
*/
* @post (arr != null AND
* occurrences(4,arr) == occurrences(5, arr) AND
* arr[arr.length – 1] != 4 AND
* forall 0 <= i < arr.length-2, arr[i] == 4 ==> arr[i+1] != 4)
<== *
* (forall 0 <= i < arr.length-1, $prev(arr[i]) == arr[i] AND
* $ret != arr AND
* permutation(arr, $ret) AND
* $ret.length == arr.length AND
* forall 0 <= i < arr.length-1, arr[i] == 4 ==> $ret[i] == 4 AND
* forall 0 <= i < $ret.length-2, $ret[i]==4 ==> $ret[i+1] == 5)
/
任务是使用这些前置条件更改给定数组,以便在4的任何外观出现后5。 例如:
fix45({5,4,9,4,9,5}) - &gt; {9,4,5,4,5,9}
fix45({1,4,1,5}) - &gt; {1,4,5,1}
这就是我写的(它有效):
public static int pos (int[] arr, int k){
while (arr[k]!=5){
k=k+1;
}
return k;
}
public static int[] fix45(int[] arr){
int k=0;
for(int i = 0; i<=arr.length-1; i++){
if (arr[i] == 4){
int place= pos(arr,k);
arr[place]=arr[i+1];
arr[i+1]=5;
k=k+3;
}
}
return arr;
}
我的任务: 1.这两份合同有什么区别? 我真的应该讨论前提条件吗? 3.这个“和”是什么意思? 4.我的代码应该如何根据第二份合同进行更改?
谢谢你们。
答案 0 :(得分:4)
1.
两份合约有什么区别?
第一个将参数限制为方法,它们必须满足给定的前提条件。例如,arr
参数不能为空,否则为错误。在第二个例子中,你可以传递你想要的任何参数,但是:当参数是某个特定的布局/结构(不是null,得到相同数量的4和5,...)时,它必须返回/更改数组这样一种方式来匹配结论(我相信必须转动<== *
处的箭头。)
2.
我应该实际检查前提条件
是的,特别是如果你这样说的话。另外,它应该在javadoc注释中提及它应该说明什么时候发生的事情。 Javadoc获得了@throws
关键字。像
/**
* (...)
* @throws NullPointerException If the argument is <code>null</code>.
* @throws IllegalArgumentException If the number of 4's and 5's is not the same.
*/
3.
这个“和”是什么意思?
AND
是logical conjunction。如果两个参数/语句都是true
,则评估为true
。
4.
我的代码应该如何根据第二份合同进行更改?
除非符合假设(==>
之前的部分),否则不应以任何方式抛出和异常或更改数组。在这种情况下,必须根据结论更改数组(和/或返回值)。
答案 1 :(得分:2)
我不能声称知道,但这是我对给定条件的解释。
首先,您的代码实际上似乎没有遵循任何合同。它违反了$ret != arr
和forall 0 <= i < arr.length-1, $prev(arr[i]) == arr[i]
条件。
因为两个条件都要求你不要改变arr(通过如果不满足先决条件,第一个需要抛出错误。第二个意味着你应该只返回一些内容(例如forall 0 <= i < arr.length-1, $prev(arr[i]) == arr[i]
后置条件,并且第一个中的所有条件(前置和后置)都是第二个中的后置条件,合同是相同的null
或arr
或任何其他值){ {1}}为空或无效。
当违反前提条件时,可能应该抛出非法参数例外(但也许你应该告诉给你合同的人)。
我假设arr
逻辑上并且将条件放在一起,就像它们已被单独描述一样(但可以与AND
一起使用以获得更大的灵活性)
它不应该是。当不满足前提条件时,不要抛出OR
,而是返回IllegalArgumentException
编辑评论:
我相信null
表示返回值不能与$ret != arr
引用相同的int[]
。也就是说,您必须在函数中的某处创建一个新的arr
并返回它。
int[]
表示forall 0 <= i < arr.length-1, $prev(arr[i]) == arr[i]
的每个元素(由于某种原因除了最后一个元素)必须与之前(调用函数之前)相同。即你不能改变它(很多)。这与要求创建和返回全新数组一致。