您的位置:首页 > 编程语言 > Java开发

[Java] 作业5 (数组)

2016-05-04 23:34 435 查看
Q10

public class Test {
public static void main(String args[]) {
int a[] = new int[5];
boolean b[] = new boolean[5];
System.out.print(a[1]);
System.out.println(b[2]);
}
}
在第 3 行和第 4 行,我们分别创建了两个数组:

    - 含有5个 int 元素的数组 a

    - 含有5个 boolean 元素的数组 b

根据Oracle官文文档 -- 4.12.5. Initial Values of Variables

Every variable in a program must have a value before its value is used.

Each class variable, instance variable, or array component is initialized with a default value when it is created (§15.9, §15.10):

    - For type int, the default value is zero, that is, 0.

    - For type boolean, the default value is false.

    - ... (byte, long, float, double等类型可以点击上述链接,自行查阅)

程序中的每个变量必须在使用前拥有一个值;

在数组创建时,其组件(每个元素)都会初始化一个默认值:

    - int 类型的默认值是 0

    - boolean 类型的默认值是 false

Q15

public class Test {
public static void main(String[] args) {
int b[][] = { { 1 }, { 2, 2 }, { 2, 2, 2 } };
int sum = 1;
for (int i = 0; i < b.length; i++) {
for (int j = 0; j < b[i].length; j++) {
sum *= b[i][j];
}
}
System.out.println(sum);
}
}
考察多(二)维数组的知识,这方面的知识可以参考:

    - 《Java核心编程 卷1 基础知识》 (原书第9版) 3.10.6 多维数组

    - 最权威的Oracle官方文档:10.6. Array Initializers

Q18

预备知识

try, catch, finally的用法大概是:

try {
// Do your task here
} catch (ExceptionType e) {
// Program will enter this section only if exception occur (threw)
} finally {
// Program will enter this section whatever there is an exception or not.
}
在try块中,我们可以执行任务,在执行任务的过程中,可能会出现异常(比如说对含有 n 个元素的数组 a 进行 a
这样的下标访问 —— 因为 a 只能支持 a[0, 1, ..., n - 1] 这样的下标访问),因此程序会抛出异常。

在catch块中,我们可以捕获这个异常,并且执行我们想要做的事

    - 比如打印信息:System.out.println("There is an exception here."); 

    - 这样做的好处是,在实际项目中,可以通过try-catch显式地定制处理异常的方法,而不会像大家在实验课上因为一些异常,导致程序直接中止(abort). 试想如果你的服务器上正运行着提供给上万个用户使用的APP, 你并不希望因为无法处理某一个用户的请求,而使整个服务器、APP中止。

在finally块中,无论是否发生异常,这个块中的内容都会被执行。finally块是可选的(optional), 但try-catch必须要搭配起来使用,所以下述语句也是符合语法的:

try {
// Do your task here
} catch (ExceptionType e) {
// Handle the exception here
}
回到原题
import java.util.Scanner;

public class Test {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 两个case
for (int i = 1; i <= 2; ++i) {
// 每个case的第一个数字代表:数组中将包含几个元素
int n = in.nextInt();
int[] a = new int
;
// 通过循环,输入数字a0, a1, ..., a(n-1),并分别赋值给a[j], (0 < j < n)
for (int j = 0; j < n; ++j)
a[j] = in.nextInt();
try {
int sum = 0;
for (int j = 0; j <= n; ++j) {
if (a[j] % 10 == 0)
break;
sum = sum + a[j];
}
System.out.print("sum=" + sum);
} catch (ArrayIndexOutOfBoundsException e) {
System.out.print("@@@");
} finally {
System.out.print("###");
}
}
in.close();
}
}
题目输入为:

4

12 45 67 20

2

21 31

第一个case

首先,n = 4, 输入 4 个数字,并初始化数组 a, 此时 a = {12, 45, 67, 20};

其次,我们在循环中遍历数组每个元素,并进行累和操作,当 j = 3 时,由于 a[3] % 10 == 0 成立,break:语句生效,跳出循环,打印"sum=124".

最后,执行finally语句,输出 "###"

第二个case

首先,n = 2, 输入 2 个数字,并初始化数组 a, 此时 a = {21, 31};

其次,我们在循环中遍历数组每个元素,并进行累和操作

    - 当 j = 0 或 1 时,sum += a[j]

    - 当 j = 2 时,if (a[j] % 10 == 0) 将访问数组 a 的第 2 个元素,这会发生数组的访问越界。抛出异常,所以在此没有打印"sum=..."

再次,catch语句捕获了这个ArrayIndexOutOfBoundsException. 输出 "@@@"

最后,执行finally语句(在此强调,这个语句无论是否出现异常,都将被执行),输出 "###"

Q28

要解决这题,只要把题目复制到eclipse下,ctrl + shift + f重新排版一下就可以:

public class Test {
public static void main(String[] args) {
int[] x = new int[5];
int i;
for (i = 0; i < x.length; i++)
x[i] = i;
System.out.println("i: " + i);
System.out.println(x[i]);
}
}
仍然不理解的同学,可以考虑一下上面程序的第7行输出的 i 的值会是多少。

Q39

public class Test {
public static void main(String[] args) {
int[] x = { 1, 2, 3, 4, 5 };
// 调用increase(x)时,编译器将在一份新的内存空间中,创建一个跟本地的x的值相同的变量(我们姑且称之为x2)
// x2的值和x相同,所以x2和x一样,指向了同一个数组的起始位置
increase(x);
int[] y = { 1, 2, 3, 4, 5 };
// 调用increase(y[0])时,编译器将在一份新的内存空间中,创建一个跟本地的y[0]的值相同的变量(称为y2)
// 虽然这个y2的值跟y[0]相同,但因为它们分别指向不同的内存空间
// 所以,在increase(y2)中即使y2++, 仍然没有改变y指向的数组中的内容
increase(y[0]);
System.out.println(x[0] + " " + y[0]);
}

// 为避免混淆,我们在此将参数名从 x 改为 x2
// 事实上,无论参数名叫什么,都不会影响程序最终的结果
public static void increase(int[] x2) {
for (int i = 0; i < x2.length; i++)
x2[i]++;
}

public static void increase(int y) {
y++;
}
}
根据语法,在发生参数传递的时候,无论参数的类型是什么,都会在一份新的内存空间中,将原来的值拷贝一份:

    - 对于基础类型(类型名都是小写字母的),如int, long, double等,在调用方法中(callee)中修改形参,并不会影响caller中实参的值——形参和实参分别指向不同的内存空间;

    - 对于数组、String等,同样会在一份新的内存空间中,将原来的值拷贝一份。以数组 x 为例:

        - 这里的拷贝并不代表将整个数组赋值一遍,而是将数组第一个元素的内存地址拷贝一份作为 x2 传递给调用方法(callee). 

        - 所以在 callee 中,通过下标访问去修改 x2 指向的内容,等价于修改 calle r中 x 数组的内容。这是由于:

            - 在方法调用\参数传递时,采用的copy by value策略,决定了 caller中的x 和 callee中的x2 的值相同;相同的值,则意味着 x 和 x2 都指向着相同的内存空间。

Q40

// Program I
public class Test {
public static void main(String[] args) {
int[] list = { 1, 2, 3, 4, 5 };
reverse(list);
for (int i = 0; i < list.length; i++)
System.out.print(list[i] + " ");
}

public static void reverse(int[] list) {
int[] newList = new int[list.length];
for (int i = 0; i < list.length; i++)
newList[i] = list[list.length - 1 - i];
list = newList;
}
}

// Program II
public class Test {
public static void main(String[] args) {
int[] oldList = { 1, 2, 3, 4, 5 };
reverse(oldList);
for (int i = 0; i < oldList.length; i++)
System.out.print(oldList[i] + " ");
}

public static void reverse(int[] list) {
int[] newList = new int[list.length];
for (int i = 0; i < list.length; i++)
newList[i] = list[list.length - 1 - i];
list = newList;
}
}
首先,要明确一点:程序 I 和程序 II 中的reverse方法,是完全等价的:

    - 接受一个int[]类型的参数,将数组中的元素翻转

其次,程序 I 和程序 II 唯一的区别,就是在main方法中,采用了不同的参数名用来表示{ 1, 2, 3, 4, 5 }. 但换个名字,最终是不会改变结果的。

Q41

参考《Java语言程序设计-基础篇》第8版:

    6.6 给方法传递数组

Q46

试运行下述程序,并理解运行结果;

在理解运行结果后,可查阅课本、参考书加深理解。

public class Test {
public static void main(String[] args) {
double[][] x = new double[4][5];
System.out.println("x.length = " + x.length);
for (int i = 0; i < x.length; ++ i)
System.out.println("x[" + i + "] = " + x[i].length);
}
}


Q48

参考《Java核心技术 卷1 基础知识》第9版:

    - 3.10.7 不规则数组

        - 对多维数组掌握不够好的同学,可参考 3.10.6 多维数组

Q52

预备知识:

// 通过形式如下所述的for语句,我们可以遍历elements中的每个元素
for (DataType element: elements) {
// 如果elements的类型是double[], 那么element的类型应该是double
// 如果elements的类型是long[][], 那么element的类型应该是long
}
实验:

// 下述程序将输出1 2 3 (每个数字各占一行)
int[] array = {0, 1, 2};
for (int elem: array) {
System.out.println(elem);
}


回到原题:

public class Test {
public static void main(String[] args) {
int[][] values = { { 3, 4, 5, 1 }, { 33, 6, 1, 2 } };
int v = values[0][0];
for (int[] list : values)
for (int element : list)
if (v > element)
v = element;
System.out.print(v);
}
}


values是一个二维数组,我们通过for遍历values中的每个元素,所以每个list都是一个一维数组int[]

    - 我们通过for遍历list中的每个元素,所以每个element都是一个整型int
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Java