圣思源Java视频36节练习源码分享(自己的190+行代码对比老师的39行代码)

题目

 * 随机生成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的关系,可以大量简化代码。

你可能感兴趣的:(java)