1.1.36 乱序检查。通过实验检查表 1.1.10 中的乱序代码是否能够产生预期的效果。编写一个程序 ShuffleTest ,接受命令行参数 M 和 N ,将大小为 M 的数组打乱 N 次切每次打乱之前都将数组重新初始化为 a[i] = i 。打印一个 M×M 的表格,对于所欲的列 j ,行 i 表示的是 i 在打乱之后落到 j 的位置的次数。 数组中的所有元素的值都应该接近于N/M。
import edu.princeton.cs.algs4.*; publicclassq1136{ /** * 随机将 double 数组中的元素排序 */ publicstaticvoidshuffle(int[] a){ int N = a.length; for (int i = 0; i < N; i++){ //将 a[i] 和 a[i..N-i] 中任意一个元素交换 int r = i + StdRandom.uniform(N-i); int temp = a[i]; a[i] = a[r]; a[r] = temp; } } publicstaticvoidmain(String[] args){ int M = StdIn.readInt();//数组大小 int N = StdIn.readInt();//打乱次数 int[] array = newint[M]; int[][] exal = newint[M][M]; for (int i = 0; i < N; i++){ for (int j = 0; j < M; j++){ //System.out.println("j:"+j); array[j] = j; } shuffle(array); for(int k = 0; k < M; k++){ exal [array[k]][k]++; //System.out.println(array[k]); } } for(int i = 0; i < M; i++){ for(int j = 0; j < M; j++){ System.out.print(exal[i][j]+"\t"); } System.out.println(); } } }
import edu.princeton.cs.algs4.*; import java.util.Arrays; publicclassq1138{ /** * 二分查找 */ publicstaticintBinarySearch(int key,int[] a){ //数组必须是有序的 int lo = 0; int hi = a.length - 1; while(lo <= hi){ //被查找的键要么不存在,要么必然存在与a[lo~hi]之中 int mid = lo + (hi - lo) / 2; if(key < a[mid]){ hi = mid - 1; } elseif (key > a[mid]) { lo = mid + 1; } else { return mid; } } return -1; } /** * 暴力查找 */ publicstaticintBruteForceSearch(int key, int[] a){ for (int i = 0; i < a.length; i++){ if (a[i] == key){ return i; } } return -1; } publicstaticvoidmain(String[] args){ int[] whitelist = In.readInts(args[0]); Arrays.sort(whitelist); long t1=System.currentTimeMillis(); while(!StdIn.isEmpty()){ //读取键值,如果不存在与白名单中则将其打印 int key = StdIn.readInt(); BinarySearch(key,whitelist);//二分 //BruteForceSearch(key,whitelist);//暴力 } long t2=System.currentTimeMillis(); System.out.println(t2 - t1); } }
在阿里云Ecs学生机上运行:
二分查找:13701毫秒 = 13.701秒
暴力查找:1925849毫秒 = 1925.849秒 大约半小时
1.1.39 随机匹配。编写一个使用 BinarySearch 的程序,它从命令行接受一个整形参数 T ,并分别会针对 N = 103, 104, 105 和 106 将一下实验运行 T 遍:生成两个大小为 N 的随机 6 位正整数数组并找出同时存在于两个数组中的整数的数量。 打印一个表格,对于每个 N ,给出 T 次实验中该数量的平均值。
import edu.princeton.cs.algs4.*; publicclassq1139{ /** * 二分查找 */ publicstaticintBinarySearch(int key,int[] a){ //数组必须是有序的 int lo = 0; int hi = a.length - 1; while(lo <= hi){ //被查找的键要么不存在,要么必然存在与a[lo~hi]之中 int mid = lo + (hi - lo) / 2; if(key < a[mid]){ hi = mid - 1; } elseif (key > a[mid]) { lo = mid + 1; } else { return mid; } } return -1; } /** * 生成大小为 N 的六位随机数组 */ publicstaticint[] buld (int N){ int[] array = newint[N]; for (int i = 0; i < N; i++){ StdOut.println("i"+ i); array[i] = StdRandom.uniform(100000, 1000000);
} return array; } /** * 做实验 * @param T 实验次数 * @param N 生成数组大小 */ publicstaticdouble[] running(int T, int N){ double[] num = newdouble[T]; for (int t = 0; t < T; t++){ int ans = 0; int[] a = buld(N); int[] b = buld(N); for(int i = 0; i < N; i++){ int c = BinarySearch(a[i], b); if(c >= 0){ ans++; } } num[t] = ans*1.0; } return num; } publicstaticvoidmain(String[] args){ StdOut.print("实验次数:"); int T = StdIn.readInt(); StdOut.println(); double[] ans = newdouble[T];//存储结果 { int N = 1000; double[] answer = running(T, N); StdOut.println("N=" + N +",T=" + T + ",平均值:"+StdStats.mean(answer)); } { int N = 10000; double[] answer = running(T, N); StdOut.println("N=" + N +",T=" + T + ",平均值:"+StdStats.mean(answer)); } { int N = 100000; double[] answer = running(T, N); StdOut.println("N=" + N +",T=" + T + ",平均值:"+StdStats.mean(answer)); } { int N = 1000000; double[] answer = running(T, N); StdOut.println("N=" + N +",T=" + T + ",平均值:"+StdStats.mean(answer)); } }