五.数组
数组是数据的有序集合。通过数组,可以将一组相同类型的数据组织在一起,并有助于对这组数据进行有效处理。在java中,数组被作为对象处理。
1.一维数组
(1) 数组的定义
一维数组的定义方式为:
type arrayName[ ] 或 type[] arrayName;
- 类型(type)表示数组的类型,称为基类型。可以是Java中任意的数据类型,包括基本类型和复合类型。
- 数组名arrayName为一个合法的标识,[ ]指明该变量arrayName是一个数组类型变量。
例如:int intArray[ ];String[ ] args; int[] a,b,c; Date dateArray[ ];
与C、C++不同,Java在定义数组时不发生内存的分配,因此[ ]中不用指出数组中元素的个数,即数组长度,而且对于经过如上定义的一个数组是不能访问数组元素的,必须经过初始化后,才能引用数组的元素。
(2) 数组的初始化
一维数组定义之后,必须经过初始化才可以引用。数组的初始化分为静态初始化和动态初始化两种:
静态初始化:在定义数组的同时对数组元素进行初始化。
例如: int intArray[]={1,2,3,4,5}; String str[]={“java”,”basic”,”fortran”};
动态初始化:使用运算符new为数组分配空间。
①对于基类型为基本类型的数组
int a[]=new int[10];
double b[]=new double[5];
String s[]=new String[2];
②对于基类型为复合类型的数组,需要经过两步内存空间分配。
首先: 为数组分配内存空间
然后: 为每个元素分配内存空间
Student stu[];
stu=new Student[2];
stu[0]=new Student(“李明”) ;
stu[1]=new Student (“王伟”);
另外,与C、C++中不同,Java对数组元素要进行越界检查以保证安全性。同时,对于每个数组都有一个属性length指明它的长度,例如:
intArray.length指明数组intArray的长度。
2.多维数组
在任何语言中,多维数组都被看作数组的数组。比 如二维数组是一个特殊的一维数组,其每一个元素 又是一个一维数组。我们主要以二维数组为例来说 明,高维数组与此类似。
(1) 二维数组的定义
二维数组的定义方式
type arrayName[ ][ ]; 例如: int intArray[ ][ ];
也可以采用另一种定义方式:type[ ][ ] arrayName;
与一维数组一样,这时对数组元素也没有分配内存,同样要使用运算符new来分配内存,然后才可以访问每个元素。
(2) 二维数组的初始化
二维数组的初始化也分为静态和动态两种。
静态初始化:在定义数组的同时为数组分配空间。
int intArray[ ][ ]={{1,2},{2,3},{3,4}};
不必指出数组每一维的大小,系统会根据初始化时给出的初始值的个数自动算出数组每一维的大小。
动态初始化:对高维数组来说,分配内存空间有下面两种方法:
1.直接为每一维分配空间,如:
type arrayName[ ][ ]=new type[arraylength1][arraylength2]
例如: int a[ ][ ]=new int[2][3];
2.从最高维开始(而且必须从最高维开始),分别为每一维分配空间,如:
String s[ ][ ]=new String[2][ ];
s[0]=new String[2];
s[0][0]=new String(“Good”);
s[0][1]=new String(“Luck”);
s[1]=new String[3];
s[1][0]=new String(“to”);
s[1][1]=new String(“you”);
s[1][2]=new String(“!”);
3、数组操作的常用方法
在java.util包中的Arrays类提供了一些操作数组的方法
——java.util.Arrays
int binarySearch(type a[], type key)
数组a必须已经排序,否则返回值无意义
当数组a中有重复的值时,该方法返回的值不确定
如果key存在,则返回它在数组a中的位置
如果不存在,则返回它的“-(插入位置-1)”
void fill(type a[], type val)
void fill(type a[], int fromIndx, int toIndex, type val)
包括a[fromIndx],但不包括a[toIndex]
fromIndx== toIndex时,范围是一个空的范围
boolean equals(type a[], type a2[])
两个数组变量指向同一个数组对象则返回true
两个null数组是相等的
void sort(type a[])
void sort(type a[], int fromIndx, int toIndex)
void sort(type a[], Comparator c)
void sort(type a[], int fromIndx, int toIndex, Comparator c)
包括a[fromIndx],但不包括a[toIndex]
fromIndx== toIndex时,范围是一个空的范围
排序算法都具有n*log(n)的计算复杂性,效率高
排序算法都保证稳定,即排序算法不会改变相等元素的顺序
对不同类型的数组,算法的实现并不完全相同
调用Arrays.sort();
数组的复制
——java.lang.System
void arraycopy(Object src, int src_position, Object dst, int dst_position, int length)
范围不能越界
可对任何同类型的数组进行复制
数组复制过程中做严格的类型检查
更详细的内容参见JDK文档
4.题目
(1)单选题
1.1 关于一维数组的定义形式,哪个是错误的?
A.int intArr=new int[10];
B.int intArr[]=new int[10];
C.int intArr[]={1,2,3,4,5};
D.int intArr[]=new int[]{1,2,3,4,5};
E.int intArr[]={1,2,3,4,5};
1.2 数组的定义为:int[] arr=new int[10];
如何获得数组的长度?
A.arr.length()
B.arr.size()
C.arr.length
D.arr.size
1.3 执行完以下代码int[ ] x = new int[25];后,以下哪项说明是正确的( )
A.x[24]为0
B.x[24]未定义
C.x[25]为0
D.x[0]没有数值存在
1.4 关于char类型的数组,说法正确的是( )。
A.其数组的默认值是'A'
B.可以仅通过数组名来访问数组
C.数组不能转换为字符串
D.可以存储整型数值
1.5 下面关于数组声明和初始化的语句那个有语法错误?( )
A.int a1[]={3,4,5};
B.String a2[]={"string1","string1","string1"};
C.String a3[]=new String(3);
D.int[][] a4=new int[3][3];
1.6 若int a[][]={{123,345,334},{1,2},{3,4}}; 则 a[2][1]=( )。
A.1
B.3
C.2
D.4
(2)程序填空题
2.1 求一个二维数组中每行的最大值和每行的和
以下程序的功能是求一个二维数组中每行的最大值和每行的和。
输入样例
3
1 2 3
6 5 4
7 9 8
输出样例
1 2 3 3 6
6 5 4 6 15
7 9 8 9 24
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc=new Scanner( System.in );
int n=sc.nextInt();
int a[][]=new int[n][n];
int b[]=new int[n];
int c[]=new int[n];
for(int i=0;i<a.length;i++){
for(int j=0;j< a[i].length ;j++){
a[i][j]=sc.nextInt();
}
}
int max,s;
for(int i=0;i<a.length;i++){
max=a[i][0];
s=0 ; //2 分
for(int j=0;j<a[i].length;j++){
if(a[i][j]>max){
max=a[i][j] ; //2 分
}
s+=a[i][j];
}
b[i]=max;
c[i]=s;
}
for(int i=0;i<a.length;i++){
for(int j=0;j<a[i].length;j++){
System.out.printf("%3d", a[i][j] );
}
System.out.printf("%3d%3d",b[i],c[i]);
System.out.println();
}
}
}
2.2 输出Fibonacci数列
用数组来求Fibonacci数列问题,打印前20项数列,每行打印4个数。
public class Main {
public static void main(String[] args) {
int f[]=new int[20];
f[0]=1;
f[1]=1;
for(int i=2;i<20;i++){
f[i] = f[i - 2] + f[i - 1] ;//3 分
}
for( int i = 0 ;i<20;i++){
System.out.printf("%12d",f[i]);
if( (i+1)%4==0 )
System.out.println();
}
}
}
(3)函数题
3.1人口统计
本题运行时要求键盘输入10个人员的信息(每一个人信息包括:姓名,性别,年龄,民族),要求同学实现一个函数,统计民族是“汉族”的人数。
函数接口定义:
public static int numofHan(String data[])
其中 data[]
是传入的参数。 data[]
中的每一个元素都是一个完整的人员信息字符串,该字符串由“姓名,性别,年龄,民族”,各项之间用英文半角的逗号分隔。函数须返回 值是汉族的人数。
裁判测试程序样例:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
final int HUMANNUM=10;
String persons[]=new String[HUMANNUM];
Scanner in=new Scanner(System.in);
for(int i=0;i<persons.length;i++)
persons[i]=in.nextLine();
int result=numofHan(persons);
System.out.println(result);
}
/*在此处给出函数numofHan()*/
}
输入样例:
Tom_1,男,19,汉族
Tom_2,女,18,汉族
Tom_3,男,20,满族
Tom_4,男,18,汉族
Tom_5,男,19,汉族人
Tom_6,女,17,汉族
Tom_7,男,19,蒙古族
汉族朋友_1,男,18,汉族
Tom_8,male,19,老外
Tom_9,female,20,汉族
输出样例:
7
代码:
public static int numofHan(String data[]){
int n=0;
for(int i=0 ; i<data.length ; i++){
if(data[i].indexOf("汉族")>=0){//也可以写成data[i].indexOf("汉族",5)>=0
n++;
}
}
return n;
}
indexOf() 方法有以下四种形式:
public int indexOf(int ch): 返回指定字符在字符串中第一次出现处的索引,如果此字符串中没有这样的字符,则返回 -1。
public int indexOf(int ch, int fromIndex): 返回从 fromIndex 位置开始查找指定字符在字符串中第一次出现处的索引,如果此字符串中没有这样的字符,则返回 -1。
int indexOf(String str): 返回指定字符在字符串中第一次出现处的索引,如果此字符串中没有这样的字符,则返回 -1。
int indexOf(String str, int fromIndex): 返回从 fromIndex 位置开始查找指定字符在字符串中第一次出现处的索引,如果此字符串中没有这样的字符,则返回 -1。
(4)编程题
4.1 使用二维数组实现Matrix(矩阵)。
使用二维数组实现Matrix(矩阵)。
1. 定义Matrix(矩阵)类,要求如下:
a) 变量:matrix(int型二维数组),row(行数),column(列数);
b) 方法:实现两个矩阵的乘法,所有方法将返回操作后的结果矩阵。(两个矩阵的乘法:一个m×n的矩阵a(m,n)乘一个n×p的矩阵b(n,p),会得到一个m×p的矩阵c(m,p)。矩阵的行数和列数自定。)
c) 定义构造方法。
2. 编写主类,测试Matrix类。包括:构建对象,测试每一个方法,并将测试结果输出到屏幕上。
输入格式:
按下面格式输入行数、列数和矩阵:
矩阵1:
2 3
1 2 3
4 5 6
矩阵2:
3 2
7 8
9 0
1 2
输出格式:
按下面格式输出乘积矩阵,每行后面有一个空格符和回车换行符:
28 14
79 44
输入样例:
2 3
1 2 3
4 5 6
3 2
7 8
9 0
1 2
输出样例:
28 14
79 44
代码:
import java.util.*;
public class Main{
public static void main(String []args){
Scanner s = new Scanner(System.in);
int n1 = s.nextInt();
int m1 = s.nextInt();
int a1[][] = new int[n1][m1];
for(int i =0;i<n1;i++){
for(int j=0;j<m1;j++){
a1[i][j] = s.nextInt();
}
}
Matrix a= new Matrix(n1,m1,a1);
int n2 = s.nextInt();
int m2 = s.nextInt();
int a2[][] = new int[n2][m2];
for(int i =0;i<n2;i++){
for(int j=0;j<m2;j++){
a2[i][j] = s.nextInt();
}
}
Matrix b = new Matrix(n2,m2,a2);
Matrix c = new Matrix(a.row,b.column,new int[a.row][b.column]);
c = c.multiply(a,b);
for(int i =0;i<c.row;i++){
for(int j=0;j<c.column;j++){
System.out.print(c.matrix[i][j]+" ");
}
System.out.println();
}
}
}
class Matrix{
int [][] matrix;
int row;
int column;
Matrix(int row,int column, int[][]matrix){
this.row = row;
this.column = column;
this.matrix = matrix;
}
Matrix(){
}
public Matrix multiply(Matrix m1,Matrix m2){
Matrix mat=new Matrix( m1.row, m2.column,new int[m1.row][m2.column]);
for (int i = 0; i < m1.row; i++) {
for (int j = 0; j < m2.column; j++) {
for (int k = 0; k <m1.column; k++) {
mat.matrix[i][j] += m1.matrix[i][k]*m2.matrix[k][j];
}
}
}
return mat;
}
}
注意:
public Matrix multiply(Matrix m1,Matrix m2){
Matrix mat=new Matrix( m1.row, m2.column,new int[m1.row][m2.column]);
for (int i = 0; i < m1.row; i++) {
for (int j = 0; j < m2.column; j++) {
for (int k = 0; k <m1.column; k++) {
mat.matrix[i][j] += m1.matrix[i][k]*m2.matrix[k][j];
}
}
}
return mat;
}
4.2 程序改错1:对象与数组
修改如下程序的语法错误和逻辑错误,使程序运行结果如下:
//--------------------Main.java
public class Student {
private String name;
private double score;
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
public double getScore(){
return score;
}
public void setScore(double score){
this.score =score;
}
public void toString( ){
return this.name + "--" +this.score ;
}
}
public class Main {
public static void main(String args[]) {
String []name = {"Tom","Jim","Apple","Rose","Jack" ,"Lucy"};
double [] score = {98,76,85,66,72};
Student [] sGroup = new Student[ name.length ];
for( int i = 0 ; i < sGroup.length ; i++)
sGroup[i] = new Student (name[i], score[i]);
System.out.println("Student");
for( int i = 0 ; i < sGroup.length ; i++)
System.out.println(sGroup[i]);
System.out.println("end");
}
}
输入格式:
无。
输出格式:
Student
Tom--98.0
Jim--76.0
Apple--85.0
Rose--66.0
Jack--72.0
Lucy--0.0
end
输入样例:
无
输出样例:
Student
Tom--98.0
Jim--76.0
Apple--85.0
Rose--66.0
Jack--72.0
Lucy--0.0
end
代码:
class Student {
private String name;
private double score;
//添加构造器
Student(String n, double s){
name = n;
score = s;
}
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
public double getScore(){
return score;
}
public void setScore(double score){
this.score =score;
}
public String toString( ){
return this.name + "--" +this.score ;
}
}
public class Main {
public static void main(String args[]) {
String []name = {"Tom","Jim","Apple","Rose","Jack" ,"Lucy"};
double [] score = {98,76,85,66,72};
Student [] sGroup = new Student[ name.length ];
for( int i = 0 ; i < sGroup.length ; i++){
//注意"Lucy"的成绩问题
if(i < score.length){
sGroup[i] = new Student (name[i], score[i]);
}
else{
sGroup[i] = new Student (name[i], 0);
}
}
System.out.println("Student");
for( int i = 0 ; i < sGroup.length ; i++)
System.out.println(sGroup[i]);
System.out.println("end");
}
}
4.3 数组乱炖
定义一个整型数组a,数组的长度n通过键盘输入,并通过键盘给数组a赋值,赋值后完成下列操作:
1.一次性输出整个数组a的元素
2.将数组a的数据复制到数组b中
3.对数组a进行排序,并一次性输出排序后数组a的元素
4.通过键盘输入一个数,判断该数是否存在数组中,如果存在输出该数所在的下标,不存在输入no
5.对数组a中的下标为0的元素到下标为2个(不包括2)数组元素,赋值为9,然后一次性输出整个数组的值
6.判断数组a和数组b是否相同(数组元素内容相同),如果相同输出yes,否则输出no
输入格式:
第一行输入数组a的长度
第二行输入数组a的各个元素(用空格隔开)
第三行输入要查询的元素
输出格式:
对每一组输入,在第一行输出数组a。
第二行输出数组b
第三行输出排序后的数组a
第四行输出查询后结果
第五行输出填充数据后的数组a
第六行输出两个数组判断的结果
输入样例:
在这里给出一组输入。例如:
5
2 1 3 5 6
7
5
4 3 7 6 8
7
输出样例:
在这里给出相应的输出。例如:
[2, 1, 3, 5, 6]
[2, 1, 3, 5, 6]
[1, 2, 3, 5, 6]
no
[9, 9, 3, 5, 6]
no
[4, 3, 7, 6, 8]
[4, 3, 7, 6, 8]
[3, 4, 6, 7, 8]
3
[9, 9, 6, 7, 8]
no
代码:
import java.util.Arrays;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n= sc.nextInt();
if (n>0){
int[] a=new int[n];
int[] b=new int[n];
for (int i = 0; i < n; i++) {
a[i]= sc.nextInt();
}
System.out.println(Arrays.toString(a));
System.arraycopy(a, 0, b, 0, a.length);
System.out.println(Arrays.toString(b));
Arrays.sort(a);
System.out.println(Arrays.toString(a));
int m= Arrays.binarySearch(a,sc.nextInt());//这里不能使用顺序查找
if(m>-1) System.out.println(m);//下标有效则找到
else System.out.println("no");
if (n>=2){
a[0]=9;
a[1]=9;
}
System.out.println(Arrays.toString(a));
if (Arrays.equals(a,b)) System.out.println("yes");
else System.out.println("no");
}
}
}