"Daily Algorithm · Basic Knowledge" Prepare for the interview, stick to the first chapter of the algorithm - logarithm!


foreword

Pay attention to the following scenarios:

  • When writing an algorithm program, we often cannot verify it by manually inputting various test data, and we cannot find corresponding questions on the OJ platform for verification.
  • In some cases with a large sample size, we often cannot consider all edge cases.
  • Some greedy algorithms are difficult to verify mathematically. How should we judge whether the algorithm program is correct?

In this case, we need to use a logarithm!

1. What is a logarithm

Usually after we implement an algorithm ourselves, we cannot judge whether the algorithm is completely ok. If we verify it on the competition platform, it will usually only tell you if there is any error. If there is an error, it will not tell you where there is a problem. For ranking It is very troublesome to be wrong, so the logarithm was born out of nowhere. The logarithm is to use an absolutely correct method to combine the sample data generated by the random machine . If your algorithm is no problem, then and right The 100% correct method of the counter is to compare elements one by one, and it must be equals. If it returns false, there is something wrong with your algorithm.

Seeing this, I believe that everyone already has some understanding of logarithms!

The use of logarithms requires two things:

  1. For an absolutely correct way to solve this problem
  2. A randomizer to generate sample data

But the first condition can also be changed. In fact, we don’t need this method to be completely correct. We only need this method to be written by another algorithm. In this way, in the process of using the logarithm, if there is false, then That is, there is a problem with at least one method. At this time, we only need to perform breakpoint tests on the two methods for this test case. After we know that the error is found, we can continue to use the logarithm test!

2. Use a logarithm

If we want to use the selection sorting algorithm to sort the array from small to large, after writing, we don’t know whether the method we wrote is completely correct, then we need to use the logarithm to judge!

1. Implement the algorithm yourself

	//自己写的选择排序
	public static void selectionSort(int[] arr) {
    
    
		if (arr == null || arr.length < 2) {
    
    
			return;
		}
		// 0 ~ N-1  找到最小值,在哪,放到0位置上
		// 1 ~ n-1  找到最小值,在哪,放到1 位置上
		// 2 ~ n-1  找到最小值,在哪,放到2 位置上
		for (int i = 0; i < arr.length - 1; i++) {
    
    
			int minIndex = i;
			for (int j = i + 1; j < arr.length; j++) {
    
     // i ~ N-1 上找最小值的下标 
				minIndex = arr[j] < arr[minIndex] ? j : minIndex;
			}
			swap(arr, i, minIndex);
		}
	}

2. Use another algorithm to solve the problem

	//直接使用Java自带的api数组排序
	public static void comparator(int[] arr) {
    
    
		Arrays.sort(arr);
	}

3. Implement a sample data generated by a random machine

	//获得随机输入样例:随机的数组
	public static int[] generateRandomArray(int maxSize, int maxValue) {
    
    
		// Math.random()   [0,1)  
		// Math.random() * N  [0,N)
		// (int)(Math.random() * N)  [0, N-1]
		int[] arr = new int[(int) ((maxSize + 1) * Math.random())];
		for (int i = 0; i < arr.length; i++) {
    
    
			// [-? , +?]
			arr[i] = (int) ((maxValue + 1) * Math.random()) - (int) (maxValue * Math.random());
		}
		return arr;
	}

4. Use the logarithm in the main method

	//使用对数器判断自己写的选择排序算法是否正确
	public static void main(String[] args) {
    
    
		int testTime = 500000;	 //测试次数
        int maxSize = 100;       //最大测试容量:生成数组的最大容量
        int maxValue = 100;      //最大测试数据:生成随机数组中的值(-100~100)
        boolean succeed = true;  //是否对比成功
		for (int i = 0; i < testTime; i++) {
    
    
			int[] arr1 = generateRandomArray(maxSize, maxValue);//生成随机数组
			int[] arr2 = copyArray(arr1);
			selectionSort(arr1);
			comparator(arr2);
			if (!isEqual(arr1, arr2)) {
    
    
				succeed = false;
				printArray(arr1);
				printArray(arr2);
				break;
			}
		}
		System.out.println(succeed ? "True!" : "False!");

		int[] arr = generateRandomArray(maxSize, maxValue);
		printArray(arr);
		selectionSort(arr);
		printArray(arr);
	}

3. Complete code display

public class Code01_SelectionSort {
    
    

	//自己写的选择排序
	public static void selectionSort(int[] arr) {
    
    
		if (arr == null || arr.length < 2) {
    
    
			return;
		}
		// 0 ~ N-1  找到最小值,在哪,放到0位置上
		// 1 ~ n-1  找到最小值,在哪,放到1 位置上
		// 2 ~ n-1  找到最小值,在哪,放到2 位置上
		for (int i = 0; i < arr.length - 1; i++) {
    
    
			int minIndex = i;
			for (int j = i + 1; j < arr.length; j++) {
    
     // i ~ N-1 上找最小值的下标 
				minIndex = arr[j] < arr[minIndex] ? j : minIndex;
			}
			swap(arr, i, minIndex);
		}
	}

	public static void swap(int[] arr, int i, int j) {
    
    
		int tmp = arr[i];
		arr[i] = arr[j];
		arr[j] = tmp;
	}

	//绝对正确的排序方法
	public static void comparator(int[] arr) {
    
    
		Arrays.sort(arr);
	}

	/**
	 * 获得随机输入样例:随机的数组
	 * @param maxSize
	 * @param maxValue
	 * @return
	 */
	public static int[] generateRandomArray(int maxSize, int maxValue) {
    
    
		// Math.random()   [0,1)  
		// Math.random() * N  [0,N)
		// (int)(Math.random() * N)  [0, N-1]
		int[] arr = new int[(int) ((maxSize + 1) * Math.random())];
		for (int i = 0; i < arr.length; i++) {
    
    
			// [-? , +?]
			arr[i] = (int) ((maxValue + 1) * Math.random()) - (int) (maxValue * Math.random());
		}
		return arr;
	}

	//copy数组
	public static int[] copyArray(int[] arr) {
    
    
		if (arr == null) {
    
    
			return null;
		}
		int[] res = new int[arr.length];
		for (int i = 0; i < arr.length; i++) {
    
    
			res[i] = arr[i];
		}
		return res;
	}

	//判断数组是否相等
	public static boolean isEqual(int[] arr1, int[] arr2) {
    
    
		if ((arr1 == null && arr2 != null) || (arr1 != null && arr2 == null)) {
    
    
			return false;
		}
		if (arr1 == null && arr2 == null) {
    
    
			return true;
		}
		if (arr1.length != arr2.length) {
    
    
			return false;
		}
		for (int i = 0; i < arr1.length; i++) {
    
    
			if (arr1[i] != arr2[i]) {
    
    
				return false;
			}
		}
		return true;
	}

	//打印数组
	public static void printArray(int[] arr) {
    
    
		if (arr == null) {
    
    
			return;
		}
		for (int i = 0; i < arr.length; i++) {
    
    
			System.out.print(arr[i] + " ");
		}
		System.out.println();
	}

	/**
	 * 使用对数器判断自己写的选择排序算法是否正确
	 * @param args
	 */
	public static void main(String[] args) {
    
    
		int testTime = 500000;
		int maxSize = 100;
		int maxValue = 100;
		boolean succeed = true;
		for (int i = 0; i < testTime; i++) {
    
    
			int[] arr1 = generateRandomArray(maxSize, maxValue);//生成随机数组
			int[] arr2 = copyArray(arr1);
			selectionSort(arr1);
			comparator(arr2);
			if (!isEqual(arr1, arr2)) {
    
    
				succeed = false;
				printArray(arr1);
				printArray(arr2);
				break;
			}
		}
		System.out.println(succeed ? "True!" : "False!");

		int[] arr = generateRandomArray(maxSize, maxValue);
		printArray(arr);
		selectionSort(arr);
		printArray(arr);
	}
	
}

Summarize

Finally, let's look at the idea of ​​​​using the logarithm:

  1. There is a method a you want to test;
  2. Implement a method b that is absolutely correct but not complex;
  3. Implement a random sample generator;
  4. implement a method for comparing algorithms a and b;
  5. Compare method a and method b multiple times to verify whether method a is correct;
  6. If there is a sample that makes the comparison wrong, which method of the print sample analysis is wrong;
  7. When the number of samples is large, the comparison test is still correct, and it can be determined that method a is correct;

References for this article:

1. Section 1 of the Zuo Shen System Study Class
2. https://blog.csdn.net/u011679785/article/details/97117250

Guess you like

Origin blog.csdn.net/apple_51673523/article/details/126623481