第1关:数组的遍历:给小朋友分糖果
任务描述
在本关中,老师要给十个小朋友分糖果,他想利用计算机了解每个小朋友想要多少个糖果,再求出总和,请你来帮帮他。
如果通过Java语言动手编程实现上述功能,我们需要掌握数组相关的知识。
相关知识
什么是数组?
数组可以理解为:同类型元素的序列。若将有限个类型相同的变量的集合进行命名,那么这个名称为数组名。组成数组的各个变量称为数组的分量,也称为数组的元素,有时也称为下标变量。用于区分数组中各个元素的数字编号称为下标。
例如你可以声明一个数组变量,如number[100]
,来代替直接声明100个独立变量number0
,number1
,...,number99
。
总而言之,数组是在程序设计中,为了处理方便, 把具有相同类型的若干元素按无序的形式组织起来的一种数据结构。
Java数组声明
在程序中,首先必须声明数组变量,然后才能使用数组。下面是声明数组变量的语法:
dataType[] arrayName; //推荐方法
dataType arrayName[]; //语法正确,但不是最推荐的方法
请注意:虽然上述两种声明方法语法上都正确,但建议使用第一种方法来声明数组变量,因为第二种方法的语法风格是来自C/C++语言,Java之所以引进该语法是为了让 C/C++程序员能够快速理解Java语言。对于初学者而言,我们建议学习更加规范的Java语言风格,至于为什么第一种方法的语法更加规范,我们在后面的类与对象的内容中会详细阐述。
Java数组创建
Java语言使用new
操作符来创建数组,语法如下:
arrayName = new dataType[arraySize];
上述语句做了两件事:
- 使用
new dataType[arraySize]
创建了一个数组。 - 将新创建的数组的引用赋值给变量
arrayName
。
数组变量的声明和创建也可以用一条语句完成,如下所示:
dataType[] arrayName = new dataType[arraySize];
另外,你还可以在创建数组的同时对数组进行初始化赋值,参考如下:
dataType[] arrayName = {value0, value1, ..., valuek};
请注意:程序中的数组必须先声明,再创建;或者声明和创建用一条语句完成。
Java数组遍历
数组的元素是通过索引访问的,索引值也称为数组下标。数组索引从0开始,所以索引值从0到元素总数-1。
数组的元素类型和数组的大小都是确定的,所以当处理数组元素的时候,我们通常使用基本循环或者foreach
循环。
编程要求
本关的编程任务是补全右侧代码片段中的main
函数,从而完成分糖果的任务,具体要求如下:
- 用
candyArray
数组保存从命令行输入的10个int
型数据。 - 计算糖果数量的总和,用变量
sumCandies
存储糖果的总数。 - 循环输出每个小朋友需要的糖果数量,即遍历
candyArray
数组输出每个元素(注意:每个元素之间用空格分隔,但结尾不要有空格)。
评测说明
平台将自动编译补全后的代码,并生成若干组测试数据,接着根据程序的输出判断程序是否正确。
以下是测试样例:
测试输入: 1 2 3 4 5 6 7 8 9 10 预期输出: 1 2 3 4 5 6 7 8 9 10[无空格] 55
package step1;
import java.util.Scanner;
public class CandyDelivery {
public static void main(String[] args) {
int sumCandies = 0;
int[] candyArray = new int[10];
Scanner scanner = new Scanner(System.in); //用于读入测试数据
/********** Begin *********/
//用于读取下一个数据,即每个小朋友想要的糖果
// 请在此处补全循环代码
for (int i = 0 ; i < 10 ; i ++)
{
candyArray[i] = scanner.nextInt();
System.out.print(candyArray[i]);
if (i < 9) System.out.print(" ");
}
// 请在此处添加遍历数组相关代码
for ( int i = 0 ; i < candyArray.length ; i ++)
{
sumCandies += candyArray[i];
}
/********** End *********/
System.out.println();
System.out.print(sumCandies);
}
}
第2关:灵活使用Java对数组操作的方法 - 成绩统计
任务描述
小明是二班的班长,某次考试之后恰巧一班的班长生病了,老师便让小明帮着一起统计一班和二班的成绩,统计完成后老师突然想知道如果把一班和二班的成绩放在一起比较会是什么样,便把这项任务交给了小明。这可把小明难住了,你能帮帮他么?
相关知识
Java对数组的一些操作方法
跟C/C++不同,Java对数组的操作提供了很多现成和实用的方法,常用的主要包括Arrays
工具类和System.arraycopy
方法。
Arrays工具类
Java中的Arrays
类是一个实现对数组操作的工具类,包括了各种各样的静态方法,可以实现数组的排序和查找、数组的比较和对数组增加元素,数组的复制和将数组转换成字符串等功能。
注:使用Arrays
工具类需要导入包:
import java.util.Arrays;
数组排序
int[] array = {1, 5, 3, 8, 4};
Arrays.sort(array); //实现对数组元素从小到大排序,执行后array内容为{1, 3, 4, 5, 8}
注:此类中只提供升序排序,没有降序排序。
数组元素二分查找
当我们需要在数组中查询某一个关键字时,可以使用二分查找法(binarySearch
方法)。使用此方法时数组必须按升序排列好,否则结果可能错误。方法返回关键字元素的下标,如果数组中不存在该关键字,则返回-1
或者-
(插入点)。插入点是索引键将要插入数组的那一点,即第一个大于该键的元素索引。
int[] array = {1, 2, 3, 4, 6, 7};
System.out.println(Arrays.binarySearch(array, 4)); //返回值为3
System.out.println(Arrays.binarySearch(array, 5)); //返回值为-5
判断数组是否相等
可以采用equals()
方法检测两个数组是否相等,方法返回true
或false
,如果它们的内容(包括顺序)相同,那么这两个数组相等:
int[] array1 = {1, 2, 3, 4};
int[] array2 = {1, 2, 3, 4};
int[] array3 = {4, 3, 2, 1};
System.out.println(Arrays.equals(array1, array2)); //返回值为true
System.out.println(Arrays.equals(array1, array3)); //返回值为false
Java中的Arrays
工具类提供了非常多的对数组进行操作的方法,在这里就不一一例举了,大家可以查看API了解更多的方法。
System.arraycopy方法
方法原型定义为:
public static native void arraycopy(Object src, int srcPos, Object dest, int destPos, int length);
含义是复制指定源数组src
到目标数组dest
中。复制从src
的srcPos
索引开始,复制的个数是length
,复制到dest
的索引从destPos
开始。下面是一个样例:
int[] array1 = {1 ,2, 3};
int[] array2 = {4, 5, 6};
int[] array3 = new int[array1.length + array2.length];
System.arraycopy(array1, 0, array3, 0, array1.length); //将array1复制进array3,此时array3为{1, 2, 3}
System.arraycopy(array2, 0, array3, array1.length, array2.length); //接着array3的尾部将array2复制进array3,此时array3为{1, 2, 3, 4, 5, 6}
编程要求
本关的编程任务是补全右侧代码片段中Begin
至End
中间的代码,具体要求如下:
- 用
class1Grade
数组保存第一组数据,用class2Grade
保存第二组数据,每一组均是5个int
型数据。 - 用
gradeCount
数组保存合并后的数组,并将该数组元素按照从小到大的顺序输出。
评测说明
平台将自动编译补全后的代码,并生成若干组测试数据,接着根据程序的输出判断程序是否正确。
以下是测试样例:
测试输入: 1 3 5 7 9 0 2 4 6 8 预期输出: 0 1 2 3 4 5 6 7 8 9
package step2;
import java.util.Scanner;
import java.util.Arrays;
public class MarkStatistics {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int[] class1Grade = new int[5];
int[] class2Grade = new int[5];
int[] gradeCount = new int[class1Grade.length + class2Grade.length];
/********** Begin *********/
for (int i=0;i<class1Grade.length;i++){
class1Grade[i]=scanner.nextInt();
}
for (int i=0;i<class2Grade.length;i++){
class2Grade[i]=scanner.nextInt();
}
System.arraycopy(class1Grade,0,gradeCount,0,class1Grade.length);//将class1Grade赋值给gradeCount
System.arraycopy(class2Grade,0,gradeCount,class1Grade.length,class2Grade.length);//将class2Grade赋值给gradeCount
Arrays.sort(gradeCount);
/********** End *********/
for (int i = 0; i < gradeCount.length; i++) {
System.out.print(gradeCount[i]);
if (i != gradeCount.length - 1) {
System.out.print(' ');
}
}
}
}
第3关:综合运用所学知识 - 记录复原
任务描述
小明负责记录班上参加志愿活动的同学的学号,但某天中午小明睡梦之中胡乱操作电脑,不小心让一些同学的学号重复记录了,请你帮他复原。
编程要求
本关的编程任务是补全右侧代码片段中Begin
至End
中间的代码,具体要求如下:
- 用
record
数组保存从命令行输入的10个int
型数据。 - 用
recordRecovery
数组保存去除重复数据后的元素。示例:数组1 1 2 2 3 3
中删去重复的数字,即转变为1 2 3
- 按照数字大小顺序,循环输出
recordRecovery
数组。
测试说明
平台将自动编译补全后的代码,并生成若干组测试数据,接着根据程序的输出判断程序是否正确。
以下是测试样例:
测试输入: 1 2 2 3 9 9 5 5 8 8 预期输出: 1 2 3 5 8 9
package step3;
import java.util.Arrays;
import java.util.Scanner;
public class RecordRecovery {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int[] record = new int[10];
int[] recordRecovery = new int[10];
/********** Begin *********/
for(int i = 0; i < 10 ; i++ ){
if(scanner.hasNextInt()){
record[i] = scanner.nextInt();
}
}
//先进行排序
Arrays.sort(record);
recordRecovery[0] = record[0];
//将不同的项放入新的数组
int j = 0;
for(int i = 1; i < record.length; i++){
if(record[i] != recordRecovery[j]){
j++;
recordRecovery[j]=record[i];
}
}
//Arrays.sort(recordRecovery);
//这个j就是实际上有多少个真实的数据
int num = j+1;
/********** End *********/
for (int i = 0; i < num; i++) {
System.out.print(recordRecovery[i]);
if (i != num - 1) {
System.out.print(' ');
}
}
}
}