Java對數器驗證算法詳解
對數器驗證算法的正確性
對數器介紹
1.有一個你想要測的方法a;
2.實現一個絕對正確但是復雜度不好的方法b;
3.實現一個隨機樣本產生器;
4.實現對比算法a和b的方法;
5.把方法a和方法b比對多次來驗證方法a是否正確;
6.如果有一個樣本使得比對出錯,打印樣本分析是哪個方法出錯;
7.當樣本數量很多時比對測試依然正確,可以確定方法a已經正確。
我們在寫算法的時候很多情況下可能是應為沒有案例測試而找不到bug,而通過對數器我們可以很方便的進行大量的樣本測試,在這些樣本中找到算法中不正確的案例,通過這些案例我們就能夠發(fā)現我們的的程序出錯在哪?如果大樣本我們的程序都沒有出錯那么我們的程序也就可以理解為是正確的了。
/** * 生成一個長度為 0-maxLength 的 int 數組,范圍是 [minValue,maxValue)<br/> * 只有正數 無負數<br/><br/> * <p> * 用法:<br/> * int[] array = ArrayTools.randomArray(20, 5, 10);<br/> * for (int i : array) {<br/> * System.out.print(i + " ");<br/> * }<br/> * 結果如下:<br/> * 8 7 7 8 9 7 5 5 9 9 6 5 8 8 7 6 9 7 8 5<br/> * * @param maxLength 數組長度 * @param minValue 生成的數值都大于等于 minValue * @param maxValue 生成的數值都小于 maxValue * @return 生成一個長度為 0-maxLength 的 int 數組,范圍是 [minValue,maxValue) * @throws IndexOutOfBoundsException 左邊界不能大于右邊界 */ public static int[] randomArray(int maxLength, int minValue, int maxValue) { int[] array = new int[random(0, maxLength + 1)]; if (minValue > maxValue) { throw new IllegalArgumentException("左邊界不能大于右邊界"); } int range = maxValue - minValue; for (int i = 0; i < array.length; i++) { array[i] = (int) (Math.random() * range) + minValue; } return array; } /** * 生成一個 在 [minValue,maxValue) 的隨機整數 * @param minValue 最小值 * @param maxValue 最大值 * @return 在 [minValue,maxValue) 的隨機整數 */ public static int random(int minValue, int maxValue) { if (minValue > maxValue) { throw new IllegalArgumentException("左邊界不能大于右邊界"); } int rang = maxValue - minValue; return (int) (Math.random() * rang) + minValue; } /** * 檢驗數組是否是升序排列 * @param arr 待檢查數組 * @return 檢查結果 */ public static boolean isSorted(int[] arr) { if (arr.length < 2) { return true; } int max = arr[0]; for (int i = 1; i < arr.length; i++) { if (max > arr[i]) { return false; } max = Math.max(max, arr[i]); } return true; } /** * 交換 arr 數組當中 i 位置和 j 位置的元素 * @param arr 待交換數組 * @param i 第一個元素位置 * @param j 第二個元素位置 */ private static void swap(int[] arr, int i, int j) { int tmp = arr[i]; arr[i] = arr[j]; arr[j] = tmp; } /** * 選擇排序 * @param arr 待排序數組 */ public static void selectionSort(int[] arr) { if (arr == null || arr.length < 2) { return; } int N = arr.length; for (int i = 0; i < N; i++) { int minValueIndex = i; for (int j = i + 1; j < N; j++) { minValueIndex = arr[j] < arr[minValueIndex] ? j : minValueIndex; } swap(arr, i, minValueIndex); } } public static void main(String[] args) { int maxLength = 50; int maxValue = 1000; int testTimes = 1000000; for (int i = 0; i < testTimes; i++) { int[] arr1 = randomArray(maxLength, 0, maxValue); int[] arr2 = arr1.clone(); selectionSort(arr1); if (!isSorted(arr1)) { printArray(arr2); System.out.println("選擇排序錯了"); break; } } }
對數器模板
介紹:
該對數器會對我們寫的 target() 函數 進行 500000 ,每次目標數組是最大長度為 maxLength 最大值為maxValue 的整數數組, 目標值是生成一個最大值為maxValue 的整數,通過檢驗兩個函數的計算結果來比對我們寫的函數是否正確的方法。
如果我們的函數在高達 50萬次 的測試中都正確,那么就可以說明我們的函數是正確的。
- testTimes 函數的測試次數
- randomArray(maxLength, maxValue) 生成一個 最大長度為 maxLength 最大值為maxValue 的整數數組
- random(0, maxValue); 生成一個最大值為maxValue 的整數
- test(arr, num) 通過暴力方法寫的低效率函數,但是保證正確率是100%
- target(arr, num) 我們自己寫的高效率的函數,不保證100%正確,通過對數器進行檢驗模板的正確性
public static void main(String[] args) { int testTimes = 500000; int maxLength = 50; int maxValue = 100; boolean success = true; for (int i = 0; i < testTimes; i++) { int[] arr = randomArray(maxLength, maxValue); Arrays.sort(arr); int num = random(0, maxValue); if (target(arr, num) != test(arr, num)) { success = false; printArray(arr); System.out.println(num); System.out.println("判斷出錯"); System.out.println("目標函數結果 = " + target(arr, num)); System.out.println("測試函數結果 = " + test(arr, num)); break; } } System.out.println(success ? "LUCK" : "Fucking fucked"); }
到此這篇關于Java對數器驗證算法詳解的文章就介紹到這了,更多相關Java對數器內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Spring Boot利用JSR303實現參數驗證的方法實例
這篇文章主要給大家介紹了關于Spring Boot利用JSR303實現參數驗證的相關資料,文中通過示例代碼介紹的非常詳細,對大家學習或者使用Spring Boot具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧2020-05-05JAVA WEB中Servlet和Servlet容器的區(qū)別
這篇文章主要介紹了JAVA WEB中Servlet和Servlet容器的區(qū)別,文中示例代碼非常詳細,供大家參考和學習,感興趣的朋友可以了解下2020-06-06