圣思源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的关系,可以大量简化代码。

时间: 2024-08-02 11:02:56

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

圣思园java se培训总结(10-16)

圣思园java se培训总结(10-16)1.成员变量是定义在类里面的变量,局部变量是定义在方法里的变量,定义成员变量是不用初始化,在创建实例(对象)的时候会初始化默认值!但是局部变量使用前必须赋值!局部变量与成员变量同名时,在局部变量作用域内,会代替成员变量!2. new一下会做三件事:为该类的实例开辟一块堆内存空间:调用new后的有参构造或者无参构造:返回指向该对象在堆内存中的起始地址给一个对象的引用!3.java只存在值传递,没有C的引用传递(有待复习)等等,当传递的实参是基础类型时,会把

圣思园java se培训总结(69-)(Annotation,异常处理)

如果一个Annotation里面定义一个属性,名字为value,那么在使用这个Annotation的时候给value赋值有两种方式,一种是("value值")一种是(value=value值),如果属性名不是value,那么只能用第二种方法! Junit框架3.0,要测试的类需要继承TestCase类,且需要测试的方法需要以test开头起名字!4.0中,直接使用@Test 写在方法上面,就可以测试! java中的异常可以分为两类checked exception(非runtime ex

java 第36节 抽象类概述与使用

2016-06-29 1 抽象类的定义 抽象类是为子类提供一个规范. 修饰符 abstract 类名{ //类体 修饰符 abstract 返回值类型 方法名(参数列表); } 抽象方法没有方法体:public abstract void test(); 普通方法有方法体: public void test(){//方法体内的代码}; 1.定义一个类,如果这个类是抽象类,那么这个类中至少有一个抽象方法. 2.抽象类的方法不一定是抽象方法,但是含义抽象方法的类一定是抽象类. package com

圣思园java se培训总结(52-)(泛型)

泛型:变量类型的参数化 需要限定一接口的实现类,类的子类是其泛型类型时.例如,T只能用实现了List接口的类型<T extend List> 如果没有指定泛型类别,会自动用<T extend Object>,所以默认不用的时候,会接收任何java的类型,注:数组也是Object的子类 有一个自定义泛型类:GenericTest<T>{},现在声明一个引用 GenericTest<? extends List> ge=null;这个引用的意思是可以指向一个类型

圣思园java se培训总结(28-32)(Object类,String类,包装类,数组)

String 字面值赋值 字符串采用new 创建 31节关于字符串拼接,intern方法值得面试前看 包装类byte, short ,int,long,float,double,boole 数组的length属性是public final的,例如:每次初始化数组new int[6]的时候在构造方法里赋值为6,不能修改! 只声明对象数组(P[] p=new P[5]),不赋值的时候会默认为null,且不会产生对象5个P对象

圣思园java se培训总结(99-)(线程)

实现线程的两种方式 继承Thread类,覆写run()方法,因为父类Thread类中的run()方法什么都没有做 实现Runnable接口,然后作为参数传给Thread类的Thread(Runnable tagert)构造方法

圣思园java se培训总结(85-)(内部类)

85-内部类分为4种 静态内部类 在一个类的内部,由static关键字修饰的类叫做静态内部类,它的里面只能访问外部类的静态成员和方法!编译后,会生成一个 外部类$内部类.class的文件,实例化一个内部类对象时,外部类.内部类  inner= new 外部类.内部类() 成员内部类 定义在外部类中,没有static修饰的一个类,就像一个成员方法,可以使用外部类所有的成员.这个类就像一个成员一样,被所有对象拥有.在外部类中实例化,使用this.内部类().其它类中实例化时用(new 外部类()).

圣思园java se培训总结(78-)(swing的设计模式,观察者设计模式)

BorderLayout分东西南北中,默认是Frame的布局 FlowLayout是Panel的默认布局 GridLayout是网格布局!实例化一个网格布局对象时可以指定网格数量 panel必须添加到某个容器中才能显示! 事件是描述发生了什么的对象,这些对象是AWT提供好的,例如左键击单击会产生一个ActionEvent对象 事件源是发生这个事件的某个组件,例如单击某个按钮,这个按钮就是事件源 事件处理器 就是一个接收事件,处理事件的方法,用户自己写的! 单击一个按钮就会产生一个事件 (Acti

尚硅谷Java视频_jQuery 视频教程

更多Java培训.Java视频教程学习资料,请登录尚硅谷网站下载:www.atguigu.com jQuery是优秀的JavaScript框架,能使用户能更方便地处理HTML documents.events.实现动画效果,并且方便地为网站提供Ajax交互.在世界前10000个访问最多的网站中,有超过 55 6在使用jQuery. 本Java视频教程循序渐进地对jQuery的各种选择器.函数和方法调用进行了详细的讲授,更配备了大量的实例. [视频简介] jQuery 是继 Prototype 之