题目:
* 随机生成50个数字(整数),每个数字范围是[10,50],统计每个数字出现的次数
* 以及出现次数最多的数字与它的个数,最后将每个数字及其出现次数打印出来,
* 如果某个数字出现次数为0,则不要打印它。打印时按照数字的升序排列。
要求:
* 使用数组的知识完成此功能,不能使用JDK的API函数。
分析:
* 需要写一个随机数生成函数
* 需要写一个冒泡排序函数
* 需要写一个二分查找获取数组中某元素个数的函数
代码如下:
1 package Array32; 2 3 /** 4 * 随机生成50个数字(整数),每个数字范围是[10,50],统计每个数字出现的次数 以及出现次数最多的数字与它的个数,最后将每个数字及其出现次数打印出来, 5 * 如果某个数字出现次数为0,则不要打印它。打印时按照数字的升序排列。 6 * 7 * @author Administrator 8 * 9 */ 10 public class ArrayHomeTest { 11 12 public static void main(String[] args) { 13 int[] array = new int[50]; 14 // 生成10,50间的随机数的数组 15 for (int i = 0; i < 50; i++) { 16 array[i] = RandomInt(10, 50); 17 } 18 19 // 处理前打印数组 20 System.out.println("当前生成的随机数组如下:"); 21 PrintArray(array); 22 System.out.println("-------------------"); 23 24 // 为这个数组排序 25 BubbleSortX(array); 26 27 // 获取存储次数的数组(j - 10默认为指定数字与序号的一个交叉引用……实际上这样写不好,应改善) 28 int sum[] = new int[41]; 29 for (int j = 10; j <= 50; j++) {// 对比10-50中的元素与array中的元素 30 sum[j - 10] = binarySearchGetNum(array, j); 31 } 32 // 获取最多的次数(获取数组中的最大数) 33 int sumAfterSort[] = BubbleSort(sum); 34 int maxTimes = sumAfterSort[sumAfterSort.length - 1];// 升序排序后的最大 35 // 找到最大次数对应的所有数字 36 System.out.println("出现最多的数字为有:"); 37 for (int i = 0; i < sum.length; i++) { 38 if (sum[i] == maxTimes) { 39 int num = i + 10;// i + 10默认为指定数字与序号的一个交叉引用……实际上这样写不好,应改善 40 System.out.print(num + "|"); 41 } 42 } 43 System.out.println(); 44 System.out.println("出现次数为:" + maxTimes); 45 System.out.println("-------------------"); 46 47 // 打印所有的出现的数字 48 System.out.println("数字|出现次数"); 49 for (int i = 0; i < sum.length; i++) { 50 if (sum[i] != 0) { 51 System.out.printf("%4s", i + 10); 52 System.out.print("|"); 53 System.out.printf("%8s", sum[i]); 54 System.out.println(); 55 } 56 } 57 } 58 59 /** 60 * 生成int随机数,范围fromNum-toNum 61 * 62 * @param fromNum 63 * 开始数字 64 * @param toNum 65 * 结束数字 66 * @return int随机数 67 */ 68 public static int RandomInt(int fromNum, int toNum) { 69 return (int) (Math.random() * (toNum - fromNum) + fromNum); 70 } 71 72 /** 73 * 简单冒泡排序 74 * 75 * @param a 76 */ 77 public static void BubbleSortX(int[] a) { 78 79 for (int i = 0; i < a.length - 1; i++) { 80 for (int j = 0; j < a.length - 1 - i; j++) { 81 if (a[j] > a[j + 1]) {// 升序 82 int temp; 83 temp = a[j]; 84 a[j] = a[j + 1]; 85 a[j + 1] = temp; 86 } 87 } 88 } 89 90 } 91 92 /** 93 * 不影响原数组的情况下的冒泡排序 94 * 95 * @param a 96 * @return 97 */ 98 public static int[] BubbleSort(int[] a) { 99 int length = a.length; 100 int[] rtnArray = new int[length]; 101 102 // 向rtnArray中赋值,复制一个a 103 for (int i = 0; i < a.length; i++) { 104 rtnArray[i] = a[i]; 105 } 106 107 // 冒泡排序 108 for (int i = 0; i < rtnArray.length - 1; i++) { 109 for (int j = 0; j < rtnArray.length - 1 - i; j++) { 110 if (rtnArray[j] > rtnArray[j + 1]) {// 升序 111 int temp; 112 temp = rtnArray[j]; 113 rtnArray[j] = rtnArray[j + 1]; 114 rtnArray[j + 1] = temp; 115 } 116 } 117 } 118 119 return rtnArray; 120 } 121 122 /** 123 * 二分查找返回个数 124 * 125 * @param array数组必须有序 126 * @param value 127 * @return 返回个数 128 */ 129 public static int binarySearchGetNum(int[] array, int value) { 130 int low = 0;// 待查找的下限 131 int high = array.length - 1;// 待查找的上限 132 int middle = 0;// 上限与下限的中间位置 133 134 int returnValue = 0; 135 136 while (low <= high) { 137 middle = (low + high) / 2; 138 139 if (array[middle] == value) { 140 returnValue++;// 当中间数与value相等时,计数+1 141 142 // 从middle向low的方向移位,判断low侧是否有相等的(因为已经完成排序了) 143 int tempMiddle = middle; 144 if (tempMiddle > low) { 145 while (tempMiddle > low) { 146 tempMiddle--; 147 if (array[tempMiddle] == value) { 148 returnValue++; 149 } else {// 遇到第一个不同的地方跳出 150 break; 151 } 152 } 153 } 154 155 // 从middle向high的方向移位,判断high侧是否有相等的(因为已经完成排序了) 156 tempMiddle = middle; 157 if (tempMiddle < high) { 158 while (tempMiddle < high) { 159 tempMiddle++; 160 if (array[tempMiddle] == value) { 161 returnValue++; 162 } else {// 遇到第一个不同的地方跳出 163 break; 164 } 165 } 166 } 167 return returnValue; 168 } else if (value < array[middle]) { 169 high = middle - 1; 170 } else if (value > array[middle]) { 171 low = middle + 1; 172 } 173 } 174 175 return returnValue; 176 } 177 178 /** 179 * 打印指定数组 180 * 181 * @param array 182 */ 183 public static void PrintArray(int[] array) { 184 if (array == null) { 185 return; 186 } 187 for (int i = 0; i < array.length; i++) { 188 System.out.print(array[i] + " "); 189 } 190 System.out.println(); 191 } 192 }
返回结果如下:
当前生成的随机数组如下:
44 43 36 37 36 26 31 42 45 19 11 24 33 43 28 33 35 48 20 35 35 49 45 48 45 18 34 46 47 12 41 31 10 19 15 21 20 44 16 17 14 31 29 19 43 29 32 21 39 44
-------------------
出现最多的数字为有:
19|31|35|43|44|45|
出现次数为:3
-------------------
数字|出现次数
10| 1
11| 1
12| 1
14| 1
15| 1
16| 1
17| 1
18| 1
19| 3
20| 2
21| 2
24| 1
26| 1
28| 1
29| 2
31| 3
32| 1
33| 2
34| 1
35| 3
36| 2
37| 1
39| 1
41| 1
42| 1
43| 3
44| 3
45| 3
46| 1
47| 1
48| 2
49| 1
结语:
这是自己在从C#转Java中遇到第一个手工编写的Java程序练习,主要用到了数组的知识,数据结构的知识,此外需要对于Java中的引用类型和原生数据类型的传值有一定的认识。
代码本身还不是很完善啦,如常量定义,循环的简化处理等,可以做为一个参考,其中的二分查找、冒泡排序函数都可以改进以及override出更加强大的函数。
仅作为抛砖引玉,还没有深入考虑代码的优化,老师的代码我也还没看,估计比我写的好看的多。
2015-4-8 0:15:33
补充视频中老师的方法,39行代码秒杀。
1 public static void TeachersWay(){ 2 int[] count = new int[41]; 3 4 Random random = new Random(); 5 6 //生成随机数 7 for(int i = 0; i < 50; i++){ 8 int number = random.nextInt(41) + 10;//[10, 50] 9 count[number - 10]++; 10 } 11 12 //显示每个随机数的出现次数 13 for(int i = 0; i < count.length; i ++){ 14 if(0 == count[i]){ 15 continue; 16 } 17 System.out.println((10 + i) + "出现次数:" + count[i]); 18 } 19 20 int max = count[0]; 21 22 //获取次数中的最大值 23 for(int i = 0; i < count.length ; i++){ 24 if(max < count[i]){ 25 max = count[i]; 26 } 27 } 28 29 System.out.println("出现的最大次数为:" + max + "次"); 30 31 System.out.println("最大的数有:"); 32 33 //多余的循环打印出最大的数,实际上可以与上面的获取次数最大值合并 34 for(int i = 0; i < count.length; i ++){ 35 if(max == count[i]){ 36 System.out.println(i + 10); 37 } 38 } 39 }
返回结果如下:
10出现次数:2
11出现次数:2
12出现次数:1
14出现次数:4
15出现次数:2
16出现次数:1
18出现次数:2
19出现次数:1
20出现次数:2
22出现次数:3
23出现次数:1
24出现次数:3
26出现次数:3
27出现次数:1
28出现次数:1
29出现次数:3
30出现次数:1
32出现次数:1
34出现次数:2
35出现次数:1
37出现次数:1
38出现次数:1
40出现次数:1
42出现次数:1
44出现次数:1
45出现次数:2
48出现次数:4
50出现次数:2
出现的最大次数为:4次
最大的数有:
14
48
第二次总结:
对于比较大小的方法有些遗忘了,实际上老师这个方法才是比较大小的好方法。排序再去取最大值,效率上有所降低的。
整体思路上还需要改进,利用序号0~40与实际范围10~50之间差10的关系,可以大量简化代码。