educoder---Java入门-数组进阶
第1关:数组的复制
任务描述
本关任务:完成将一个数组的值复制给另一个数组。
相关知识
本关需要你完成数组的复制操作,可以分三个步骤来实现。
- 创建一个数组
arr2
,数组长度和数组arr1
相同; - 使用循环将数组1中的每一个数据赋值给数组2中对应的那一项。(即arr2[0] = arr1[0]);
- 循环输出复制之后arr2中的所有数据。
编程要求
在右侧编辑器Begin-End
中填充代码,将arr1
数组中的数据全部复制给arr2数组,最后输出arr2
中所有的数据。
3## 测试说明
我会对你的程序进行测试,如下:
测试输入:1
,3
,12
预期输出:
1
3
12
测试输入:2
,13
,11
预期输出:
2
13
11
实验代码
package step1;
import java.util.Scanner;
public class HelloWorld {
public static void main(String[] args) {
//动态构建arr1
int[] arr1 = new int[3];
Scanner sc = new Scanner(System.in);
for(int i = 0 ; i< arr1.length ; i++){
arr1[i] = sc.nextInt();
}
/********** Begin **********/
//创建数组arr2
int[] arr2 = new int[3];
//使用for循环将arr1的数据复制给arr2
for(int i=0; i
第2关:数组中元素的查找
任务描述
本关任务:完成查找字符串数组中指定字符串位置的小程序。
3## 相关知识
为了完成本关任务,你需要知道:如何判断两个字符串是否相等。
如何判断字符串相等
我们之前判断两个数是否相等使用的是符号,我们判断字符串是否相等能否用符号呢?我们来看一段代码。
String str = "hello";
String str1 = new String("hello");
System.out.println("str的值为"+str);
System.out.println("str1的值为"+str1);
System.out.println("str与str1是否相等"+(str == str1));
输出结果:
str的值为hello
str1的值为hello
str与str1是否相等false
为什么呢?
是因为==
比较的是两个对象的内存地址,我们知道变量被创建的时候就相当于在内存中开辟空间,而案例中str和str1就是占用的两块不同的空间,所以他们的内存地址是不一致的,在用==符号判断的时候就不相等了,即为false。
也许你会这样子尝试:
String str = "hello";
String str1 = "hello";
System.out.println("str的值为"+str);
System.out.println("str1的值为"+str1);
System.out.println("str与str1是否相等"+(str == str1));
这个时候的输出结果就可能会让你感觉疑惑:
str的值为hello
str1的值为hello
str与str1是否相等true
这又是什么原因呢?是因为定义String str = "hello"
和String str1 = "hello"
没有进行对象的创建,而是同时指向的一个对象,所以他们的内存地址是相同的。
问题来了,既然==不能用,那我们应该用什么呢?
在Java中判断两个字符串是否相等,需要使用equals方法;
语法:字符串1.equals(字符串2)
如果字符串1等于字符串2返回true,否则返回false;
例如:
String str = "hello";
String str1 = new String("hello");
System.out.println("str与str1是否相等"+(str.equals(str1)));
输出: str与str1是否相等true
编程要求
在右侧编辑器Begin-end处填充代码,实现在数组中查找指定字符串位置的功能。
测试说明
测试输入:张三
预期输出:张三在数组的第1个位置
测试输入:张富贵
预期输出:张富贵在数组的第5个位置
实现代码:
package step2;
import java.util.Scanner;
public class HelloWorld {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
//str为要查找的字符串
String str = sc.next();
/********** Begin **********/
//创建数组 arr 给数组赋值 {"张三","张三丰","张无忌","王二麻子","张富贵"}
String[] arr = {"张三","张三丰","张无忌","王二麻子","张富贵"};
for(int i=0; i
实验分析
- ==比较的是两个对象的内存地址。如果不创建对象,则两个变量同时指向一个对象,内存地址相同;如果创建对象,则指向两个不同的对象,内存地址不同。
- break是跳出本次循环
第4关:选择排序
任务描述
本关任务:实现数组从大到小的排序(降序排序)。
相关知识
为了解决数组排序的问题你需要先了解:选择排序。
选择排序
关于选择排序,你可以理解为一个循环打擂台的过程,还记得我们在上一章节中求数组中的最大值吗?
我们运用打擂台的原理,可以求出数组中的最大值。
核心代码:
int max = scores[0];
for (int i = 1; i < scores.length; i++) {
if(max < scores[i]){ //求最大值
max = scores[i];
}
}
这样一轮循环之后我们就可以求出数组scores
的最大值。
第一轮擂台赛求出最大值之后,我们可以对接下来的数据再进行打擂台的操作,就出剩下数据的最大值(也就是第二大的值),以此类推,就可以实现数组从大到小的排序。
实现过程
为了实现选择排序,我们需要求出最大值,并且和相比较的数据交换位置:接下来我们对数组int[] arr = {6,5,8,0,2,9}来进行第一趟循环,将最大值移动到数组的第一位。
代码实现:
int[] arr = {6,5,8,0,2,9};
for (int i = 0; i < arr.length-1; i++) {
if(arr[0] < arr[i+1]){
int temp = arr[0];
arr[0] = arr[i+1];
arr[i+1] = temp;
}
}
一次循环操作就可以找出数组中的最大值,并将其移动到数组的首位,所以对于一个长度为6的数组,我们只需要进行5(length-1)次上述操作即可将数组降序排序了。
接下来我们进行第二趟循环,求第二大的值,并将其移动到数组的第二个位置。因为我们已经求出了最大值,所以这一次循环,最大值不用参与比较。
代码实现:
结果:[9, 8, 5, 0, 2, 6]
可以发现经过两轮循环我们找出了数组中最大的两个值,并且移动他们到了数组的前两位。
现在按照上述步骤就可以实现数组的排序了,不过如果我们照搬上述代码,就会有很多冗余的代码,所以需要你来改进,怎么改进是需要你思考的。
告诉你一个秘密:使用Arrays.toString(数组)可以直接输出数组中的值哦!
如下:
输出结果:[6, 5, 8, 0, 2, 9]
思考题
本关所讲述的选择排序是一个简化版本,如果你想要学习优化版可以根据下列图片,编写出相应代码,然后在评论区贴出来哦。
上图就是一个使用选择排序将一个数组中数据从小到大排序的过程,请思考如何用代码实现上述过程。
原理:每一次从待排序的数据元素中选出最小的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完。
本关难度较大,但这是学习数组绕不过去的一关,多思考,多尝试,你能成功的,加油!
编程要求
在右侧Begin-End
区域中添加代码,实现对数组arr
的降序排序,并输出排序后的arr
数组。
测试说明
我会对你的程序进行测试;
预期输入:6,6,5,0,2,8,9
预期输出:[9, 8, 6, 5, 2, 0]
预期输入:4,3,12,1,13
预期输出:[13, 12, 3, 1]
实现代码
package step4;
import java.util.Arrays;
import java.util.Scanner;
public class HelloWorld {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
//动态创建数组
int[] arr = new int[sc.nextInt()];
for(int i = 0 ; i< arr.length ; i++){
arr[i] = sc.nextInt();
}
/********** Begin **********/
for(int i=0; i
实验分析
- 直接输出数组,使用
Arrays.toString(数组)
System.out.println(Arrays.toString(arr));
- 选择排序(降序)
第一次大循环,将数组的第一个数与后面的所有数比较(进行内层循环),循环次数为length-1
(两个数比较,循环1次,三个数比较,循环两次,以此类推),将最大值放在第一个数位置上;
第二次大循环,将数组的第二个数与后面的所有数比较(进行内层循环),将最大值放在第一个数位置上
内层循环,循环次数和外层循环相同。都是
length-1
()。比较的是第i个数和第i+1个数
第5关:冒泡排序
任务描述
本关任务:使用冒泡排序实现数组的升序排序(从小到大)。
相关知识
冒泡排序
看完上图,相信你已经能明白冒泡排序的原理了。
将序列当中的左右元素,依次比较,如果左边的元素大于右边元素则交换位置,保证右边的元素始终大于左边的元素;( 第一轮结束后,序列最后一个元素一定是当前序列的最大值;)对序列当中剩下的n-1个元素再次执行步骤1。对于长度为n的序列,一共需要执行n-1轮比较。
在代码中实现一轮比较:
输出结果:[5, 8, 0, 2, 6, 9]
编程要求
在编辑器Begin-end处填充代码,使用冒泡排序对数组arr进行升序排序,最后输出排序之后数组arr中的数据。
测试说明
预期输入:6,9,5,8,0,2,6
预期输出:[0, 2, 5, 6, 8, 9]
预期输入:4,3,12,13,0
预期输出:[0, 3, 12, 13]
实现代码
package step5;
import java.util.Arrays;
import java.util.Scanner;
public class HelloWorld {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
//动态创建数组
int[] arr = new int[sc.nextInt()];
for(int i = 0 ; i< arr.length ; i++){
arr[i] = sc.nextInt();
}
/********** Begin **********/
for(int i=0; i arr[j+1]){
int temp;
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
System.out.println(Arrays.toString(arr));
/********** End **********/
}
}
实验总结
- 冒泡排序,每一次都是相邻的两个数(j增加)在比较。且每一遍(i增加)比之前少比较一次,因为最后面的已经比较出来,不需要再比较了。