第五章循环问题数组Word格式文档下载.docx
- 文档编号:5767814
- 上传时间:2023-05-05
- 格式:DOCX
- 页数:32
- 大小:409.33KB
第五章循环问题数组Word格式文档下载.docx
《第五章循环问题数组Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《第五章循环问题数组Word格式文档下载.docx(32页珍藏版)》请在冰点文库上搜索。
如果业务中可以获取到一个确切的循环次数时可以考虑使用for循环来实现,看下面的需求:
求1-100的和、累加10次输入的数字的和、录入3名学员信息、存储5门课程成绩……,上面的需求都是可以明确确切的循环次数,故而优先用for循环。
1.1.5.逐步细化方式解决循环嵌套的问题
详见cookbook
2.1.什么是数组
首先明确,数组是一个很重要的内容,非常重要。
前面介绍的if结构、循环,解决的都是算法问题。
那什么是算法?
所谓算法就是流程,像取钱怎么取?
插卡,输入密码,输入要取钱的金额,确定。
那这个过程,第一步怎么做,第二步怎么做,判断还是循环,这就是算法。
Pascal之父NicklausWirth说过一句话并因此而得了图灵奖,这句很经典的话就是,程序即为:
算法+数据结构,所谓数据结构,简单的说就是把数据按照特定的某种结构来保存,设计合理的数据结构是解决问题的前提条件。
今天讲的数组,就是最基本的、用得最多的一种数据结构。
试想下,存储一个学员的成绩,可以声明一个整型变量score来存储,声明20个学员的考试成绩呢?
存储50个随机数呢?
存储1万个帐号呢?
声明太多的变量,显然很繁琐,并且不适合整体的操作。
像这种情况,可以使用数组这种数据结构来解决。
数组为相同数据类型的元素组成的集合,数组元素按线性顺序排列,所谓线性顺序是指除第一个元素外,每一个元素都有唯一的前驱元素;
除最后一个元素外,每一个元素都有唯一的后继元素(“一个跟一个”),可以通过元素所在位置的顺序号(下标)做标识访问每一个元素(下标从0开始,最大到元素个数-1),数组结构如下图-2所示:
图-2
从上图中可以看出,a[0]即代表第1个元素,a[1]代表第二个元素,假设数组有5个元素,则最后一个元素即为a[5-1]。
2.2.数组的定义
2.2.1.定义基本类型数组
声明数组的语法为:
数据类型[]数组名=new数据类型[大小];
示例代码如下:
1.int[]arr=newint[10];
上面的示例代码中,int[]为数组类型,表示数组中的每一个元素为int类型;
数组也是在内存中用于存储数据的,并且是存储一组数据,同样需要一个对它的引用,该引用即为arr,arr称为数组类型变量(引用);
new为特定的声明数组的关键字,后面会详细讲解,现在先记住。
数组的声明必须要有元素个数,10即为数组中元素的个数,也称为数组长度。
总结下来,定义基本类型数组的要点包括:
1.确切的数据类型:
用于开辟空间大小
2.整体的数组名字:
用于对数据的引用
3.不能缺少的“[]”
注意在定义数组时使用的new关键字,正是因为new语句,才使得数组分配到了指定大小的空间(后面详细讲解)。
声明数组的时候,int[]arr与intarr[]两种写法均可。
常用方式为int[]arr。
声明数组时不规定数组长度(可以看到声明时仅指定了int[],未指定长度),new关键字分配空间时需指定分配的空间大小(newint[10])。
2.3.数组的初始化
2.3.1.初始化数组
基本类型(数据元素为基本类型)的数组创建后,默认为其数组元素设置了初始值,元素的初始值如下所示:
byte、short、char、int、long为0;
float和double为0.0;
boolean为false。
注意,此处强调的是基本类型数组的默认值,后期会介绍数据元素为非基本类型的,它的默认初始值与基本类型不同。
在程序中很多时候需要手动设置初始值,可以在数组声明的同时进行初始化,如下代码所示:
1.int[]arr={10,23,30,-10,21};
上面的代码中,元素的个数即为数组的长度。
但是此种写法只能用于声明时的初始化,不能用于先声明后赋值的情况,例如,下面的代码会有编译错误:
1.int[]arr;
2.arr={10,23,30,-10,21};
对于已声明的数组,可以通过下面的方式对数组类型变量进行初始化:
1.int[]arr;
2.arr=newint[]{10,23,30,-10,21};
注意:
new之后的[]中不可以写长度,而元素的个数就是数组的长度。
2.4.数组的访问
2.4.1.获取数组的长度
在程序中,调用数组的length属性可以获取数组的长度,如下代码所示:
1.int[]arr=newint[]{3,6,8,9};
2.intlen=arr.length;
3.System.out.println(“数组长度为:
”+len);
上面的代码中,len即为数组的长度,输出结果为:
“数组长度为:
4”。
2.4.2.通过下标访问数组元素
若想访问数组中的元素,需要通过下标的方式,需要注意的是,数组的下标从0开始,最大到length-1,代码如下所示:
1.int[]arr=newint[]{4,5,6,8};
2.inttemp=arr[2];
//获取第3个元素,即为6
3.//交换数组下标为2和3的两个相邻元素的值,交互后的结果为:
4,5,8,6
4.inttemp=arr[2];
5.arr[2]=arr[3];
6.arr[3]=temp;
2.4.3.遍历数组元素
在实际的应用中,常常需要对数组整体进行操作,最常见的方式即为遍历数组元素,通常可选择for循环语句,循环变量作为访问数组元素的下标,即可访问数组中的每一个元素,下面的代码使用循环方式将数组的每一个元素赋值为100。
1.int[]arr=newint[10];
2.for(inti=0;
i<
arr.length;
i++){
3.arr[i]=100;
循环的计数器的变化范围从0到数组长度–1,可通过写成“小于长度”这样的条件来防止下标越界(超出范围)。
上面的代码为循环对数组元素赋值,下面两段代码为使用循环方式分别正序、逆序输出数组元素数据:
1.int[]arr=newint[5]{10,20,30,40,50};
//正序输出
2.for(inti=0;
i<
arr.length;
i++){
3.System.out.println(arr[i]);
5.int[]arr=newint[5]{10,20,30,40,50};
//逆序输出
6.for(inti=(arr.length-1);
i>
=0;
i--){
7.System.out.println(arr[i]);
8.}
2.5.数组的复制
2.5.1.System.arraycopy方法用于数组复制
若想实现数组的复制,可以使用System.arraycopy()方法,其结构如下:
1.publicstaticvoidarraycopy(Object
src,int
srcPos,Object
dest,int
destPos,int
length)
如上代码的,每一个参数的意义见下列表:
∙src:
源数组
∙srcPos:
源数组中的起始位置
∙dest:
目标数组
∙destPos:
目标数组中的起始位置
∙length:
要复制的数组元素的数量
通过下面的代码,可实现数组的复制:
1.int[]a={10,20,30,40,50};
2.int[]a1=newint[6];
3.System.arraycopy(a,1,a1,0,4);
结果:
20,30,40,50
如上方法的意义可以理解为:
将a数组的从下标1开始的4个元素复制到a1数组中,a1数组从下标0位置开始赋值。
程序执行完后,a1的值为20,30,40,50,0,0。
其交互效果如图–3所示:
图-3
2.5.2.Arrays.copyOf方法用于数组复制
使用java.util.Arrays类的copyOf方法可实现数组的复制,其结构如下所示:
1.类型[]newArray=Arrays.copyOf(类型[]original,intnewLength)
Arrays.copyOf()方法示例代码如下所示:
1.int[]a={10,20,30,40,50};
2.int[]a1=Arrays.copyOf(a,6);
上段代码执行后,a1的结果为:
10203040500,分析其执行过程为:
声明一个整型数组,数组变量名称为a,赋初始值为1020304050,声明整型数组a1,将a数组数据复制到a1数组,设置其为6个长度,因a数组只有5个元素,所以最后一位补0。
故而输出结果为10203040500。
总结出Arrays.copyOf()方法的特点如下列表所示:
∙生成的新数组是原始数组的副本;
∙newLength小于源数组,则进行截取;
(自己通过代码演示效果);
∙newLength大于源数组,则用0或null进行填充;
2.5.3.数组的“扩容”
Java语法规定,数组的长度在创建后是不可改变的,这点需要明确。
而所谓的扩容实际上是指创建一个更大的新数组并将原有数组的内容复制到其中。
可以通过Arrays.copyOf()方法,简便的实现数组的扩展,代码如下:
2.a=Arrays.copyOf(a,a.length+1);
上段代码执行后,输出a数组的数据为:
10,20,30,40,50,0。
此时a数组的长度为6,实现了所谓的“扩容”。
2.6.数组排序
2.6.1.数组的排序
对数组所施加的算法有很多,其中最常用的即为排序算法。
所谓排序,是指将数组元素按照从小到大或从大到小的顺序重新排列,当数组元素数较多时,排序算法的优劣至关重要,因为它将直接影响程序的执行效率,一般情况下,通过排序过程中数组元素的交换次数来衡量排序算法的优劣。
常用排序算法有:
插入排序、冒泡排序、快速排序等。
今天介绍的是冒泡排序。
2.6.2.数组冒泡排序算法
冒泡排序是一个非常经典的排序算法,它的排序原则为:
比较相邻的元素,如果违反最后的顺序准则(从大到小或是从小到大),则交换。
可以简化理解为:
第一次找到所有元素中最大(或最小)的放在最后一个位置上,不再变动;
第二次找到剩余所有元素中最大(或最小)的放在倒数第二个位置上,不再变动,以此类推,直到排序完成。
在进行比较时既可以采用“下沉”的方式,也可以使用“上浮”的方式实现。
冒泡排序逻辑如下图–1所示。
图-1
下面对如上示例进行详细分析,需求:
初始序列为89,50,84,57,61,20,86,升序排(小的在前,大的在后);
第一轮第一次,89与50对比,交换位置,结果:
50,89,84,57,61,20,86
第一轮第二次,89与84对比,交换位置,结果:
50,84,89,57,61,20,86
第一轮第三次,89与57对比,交换位置,结果:
50,84,57,89,61,20,86
第一轮第四次,89与61对比,交换位置,结果:
50,84,57,61,89,20,86
第一轮第五次,89与20对比,交换位置,结果:
50,84,57,61,20,89,86
第一轮第六次,89与86对比,交换位置,结果:
50,84,57,61,20,86,89
将89冒出来了,现在序列为:
第二轮第一次,50与84对比,位置不换
第二轮第二次,84与57对比,交换位置,结果:
50,57,84,61,20,86,89
第二轮第三次,84与61对比,交换位置,结果:
50,57,61,84,20,86,89
第二轮第四次,84与20对比,交换位置,结果:
50,57,61,20,84,86,89
第二轮第五次,84与86对比,位置不换
将86冒出来了,现在序列为:
第三轮第一次,50与57对比,位置不换
第三轮第二次,57与61对比,位置不换
第三轮第三次,61与20对比,交换位置,结果:
50,57,20,61,84,86,89
第三轮第四次,61与84对比,位置不换
将84冒出来了,现在序列为:
第四轮第一次,50与57对比,位置不换
第四轮第二次,57与20对比,交换位置,结果:
50,20,57,61,84,86,89
第四轮第三次,57与61对比,位置不换
将61冒出来了,现在序列为:
第五轮第一次,50与20对比,交换位置,结果:
20,50,57,61,84,86,89
第五轮第二次,50与57对比,位置不换
将57冒出来了,现在序列为:
第六轮第一次,20与50对比,位置不换
将50冒出来了,现在的序列为:
通过上面的分析总结出如下几点,找出规律,通过程序即可完成冒泡算法的实现。
∙若数组元素数为7,则排序过程需要经历6轮,因为有1个元素是不需要比较的。
∙若数组元素数为7,第1轮比较6次,第2轮比较5次,依次类推,第6轮只比较1次。
通过如上的分析,写出冒泡排序算法如下所示:
int[]arr={89,50,84,57,61,20,86};
2.
for(inti=0;
i<
arr.length-1;
i++){
3.
for(intj=0;
j<
arr.length-1-i;
j++){
4.
if(arr[j]>
arr[j+1]){
5.
inttemp=arr[j];
6.
arr[j]=arr[j+1];
7.
arr[j+1]=temp;
8.
}
9.}
10.}
2.6.3.Arrays.sort方法用于数组排序
JDK提供的Arrays.sort()方法封装了数组的排序算法,如下述代码所示:
1.int[]arr={49,81,1,64,77,50,0,54,77,18};
2.Arrays.sort(arr);
3.for(inti=0;
arr.length;
System.out.println(arr[i]);
5.}
分析上面的代码,输出结果为:
011849505464777781。
可以看到,借助于Arrays.sort()方法实现了升序排列。
JAVAFundamentalDAY05
1.九九乘法表
2.求数组元素的最大值
3.求数组元素的最大值放在最后一位
4.冒泡排序算法实现
1九九乘法表
1.1问题
在界面打印九九乘法表,效果如图-1所示:
图-1
1.2方案
此案例需要使用嵌套循环来实现。
分析图-1可以看出,九九乘法表一共需要输出九行数据,如图-2所示:
图-2
由图-2可以看出,需要使用一个for循环来控制输出的行数。
代码如下所示:
1.//i变量用于控制行数
2.for(inti=1;
10;
i++){
3.}
分析图-2中的每行,可以看出,每行中的乘法表达式的个数正好和行数相同。
每个乘法表达式中,第一个乘数从1开始,乘到最大值(当前行数),而另一个乘数正好是行数,如图-3所示:
图-3
因此,在输出每行中的内容时,还需要使用一个for循环来控制每行中输出的表达式的个数。
如果当前行为第9行,则循环的代码如下所示:
1.//假设当前行为第9行
2.inti=9;
3.for(intj=1;
j<
=i;
j++){
4.System.out.print(j+"
*"
+i+"
="
+j*i+"
\t"
);
因为行数并不固定,而是从第一行到第九行,因此,需要将两个循环嵌套起来,代码如下所示:
//j变量用于控制每行中参与计算的最大数值:
与行数相等
for(intj=1;
5.System.out.print(j+"
6.}
//每行输出完毕后,需要换行
System.out.println();
1.3步骤
实现此案例需要按照如下步骤进行。
步骤一:
定义类及main方法
首先定义一个名为MultiplicationTable的类,并在类中添加Java应用程序的主方法main,代码如下所示:
1.publicclassMultiplicationTable{
publicstaticvoidmain(String[]args){
步骤二:
构建循环
在main方法中,构建两层嵌套的for循环:
外层循环用于控制行,内层循环用于控制某行上的乘法表达式。
需要注意的是,每行输出完毕后,需要换行。
1.publicclassMultiplicationTable{
3.//i变量用于控制行数
4.for(inti=1;
5.//j变量用于控制每行中参与计算的最大数值:
6.for(intj=1;
7.
8.}
9.//每行输出完毕后,需要换行
10.System.out.println();
11.}
12.
}
13.}
隐藏
步骤三:
输出乘法表
考虑到输出界面的美观性,使用“\t”进行排版对齐代码如下所示:
7.//设置输出的格式,控制排版对齐
8.System.out.print(j+"
9.}
10.//每行输出完毕后,需要换行
11.System.out.println();
12.}
13.
14.}
上述代码中的“\t”是水平制表符,其作用为从行首开始,每8字节算一个制表位,“\t”会在当前内容结束后第一个空的制表位处连接上下文。
1.4完整代码
本案例的完整代码如下所示:
7.//设置输出的格式,使用"
控制排版对齐
8.
System.out.print(j+"
2求数组元素的最大值
2.1问题
创建程序,实现查询数组中最大值的功能,需求为:
创建一个长度为10的数组,数组内放置10个0到99之间(包含0,包含99)的随机整数作为数组内容,要求查询出数组中的最大值,并打印显示在界面上,界面效果如图-4所示:
图-4
2.2方案
首先,此案例中,首先需要创建一个长度为10的整型数组,然后使用for循环来产生10个0到99之间的随机整数,并放入数组;
然后查询数
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 第五 循环 问题 数组