Java程序设计(2021春)——第三章类的重用课后题(选择题+编程题)答案与详解
Java程序设计(2021春)——第三章类的重用课后题(选择题+编程题)答案与详解
第三章选择题
Tip:选择题部分我只针对部分我出错的或我认为有价值的题目在此整理。
3.0 导学
无
3.1.1-3.1.2 类继承的概念和语法
无
3.1.3 隐藏和覆盖
无
3.2 Object
类
无
3.3 终结类与终结方法
T2
题面
如果需要抛出异常,可能会使用下面哪些关键字
A final
B finally
C finalize
D catch
答案
B D
详解
选项中和异常相关的只有finally
和catch
。(其实这应该是没讲过,笔者目前还没接触过相关内容,先mark一下)
T3
题面
下面程序的运行结果是(忽略换行)
class C{
final public int methos(){
System.out.println("a");
return 0;
}
}
public class A extends C{
final public int method (int x){
System.out.println(x);
return 0;
}
public static void main(String[] args){
A a = new A();
C c = new C();
a.method(2);
c.method();
}
}
A 2 2
B 2 a
C 运行错误,因为C的final方法不能被重写
D 运行错误,因为A重写method时参数表不一样
答案
B
详解
由于参数表不一样,因此并非重写方法,而是定义新方法。运行结果应该为2 a。
T4
题面
不能用来修饰interface的有
A private
B public
C final
D static
答案
A C D
详解
可以修饰interface
的只有public
。可以修饰class
的有public
final
abstract
。
T6
题面
final类和方法的存在处于以下哪些方面的考虑
A 安全方面
B 设计方面
C 代码结构简单
D 能够提高运行效率
答案
A B D
详解
详见郑莉老师《Java语言程序设计(第2版)》118-119页。
3.4 抽象类
T1
题面
下面关于抽象类和抽象方法的说法中,错误的是
A 抽象类可以包含非抽象方法
B 抽象类可以包含接口方法
C 抽象类可以包含抽象方法
D 抽象类不可以被实例化
答案
B
详解
只有接口类可以包含接口方法。
3.5 泛型
T1
题面
Java泛型机制的优点有
A 可以使代码编写变得简单
B 比较安全
C 消除对Object类的强制类型转换=
D 使得代码运行性能增强
答案
A B C
详解
无
3.6 类的组合
无
3.7 小结
无
第三章编程题
T1 唯一路径
题面
给定一个M*N的网格,你需要从左上角走到右下角,每一步你只能向下移或者向右移,请计算你能走的路径个数。 输入为一行,M和N,输出为路径数
样例输入:
2 2
样例输出:
2
样例解释
无
思考和详解
与这道题类似的题笔者似乎在三年前做过(三年前的码力远超现在),应该是带有动态规划思想的,做起来类似广度优先搜索但是实现上不一样。具体来说就是只要给出M*N
的地图,对于期中任意一格,从左上角到达该格的路径数即为该格左侧和上侧相邻两格路径数之和,因此只需要从左上角格子开始,遍历每个格子,保证遍历到每个格子的时候其左侧和上侧的格子都已知即可,具体实现的时候需要对格子边界做一点初始化。但是,本题在学堂在线oj上只得了30分,相同的思路完成与这道题类似的题得到了通过,这两题确实有差别,但是笔者思考并上网查找了很久也不知道差别在哪,如果读者有想法欢迎在评论区指出或私信我,谢谢!
具体代码
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int m = in.nextInt();
int n = in.nextInt();
in.close();
int[][] arr = new int[m + 2][n + 2];
for (int i = 0; i <= m; i++) {
for (int j = 0; j <= n; j++) {
arr[i][j] = 0;
}
}
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; j++) {
if (i == 1 && j == 1) {
arr[1][1] = 1;
continue;
}
arr[i][j] = arr[i - 1][j] + arr[i][j - 1];
}
}
System.out.println(arr[m][n]);
}
}
T2 矩阵螺旋填充
题面
给定一个整数n
,生成一个以1
到nxn
的螺旋形填充的方阵。
样例输入:
3
输出:
1 2 3
8 9 4
7 6 5
样例解释
如输出所示
思考和详解
核心思路:Step1
给二维数组arr[][]
赋值;Step2
将二维数组arr[][]
按题目要求打印出来。
具体细节:在给二维数组赋值时,按照题面要求进行模拟即可,利用oper
操作标识符,x,y
坐标,ct
当前标记数字,cnt
将按此方向行进多少来确定func
方法,需要注意的是最后如果cnt
到达了0
但是ct
还未到达n*n
,则说明还差最后一个数字需要填入。
具体代码
import java.util.Scanner;
public class matrix {
public static int[][] arr;
public static int n;
public static void func(int oper, int x, int y, int ct, int cnt) {
if (ct >= n * n || x > n || y > n)
return;
else if (cnt == 0) {
arr[x][y] = ++ct;
return;
}
int i;
if (oper == 1) {
for (i = y; i <= y + cnt - 1; i++) {
arr[x][i] = ++ct;
}
func(2, x, i, ct, cnt);
} else if (oper == 2) {
for (i = x; i <= x + cnt - 1; i++) {
arr[i][y] = ++ct;
}
func(3, i, y, ct, cnt);
} else if (oper == 3) {
for (i = y; i >= y - cnt + 1; i--) {
arr[x][i] = ++ct;
}
func(4, x, i, ct, cnt);
} else if (oper == 4) {
for (i = x; i >= x - cnt + 1; i--) {
arr[i][y] = ++ct;
}
func(1, i + 1, y + 1, ct, cnt - 2);
}
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
n = in.nextInt();
in.close();
arr = new int[n + 20][n + 20];
func(1, 1, 1, 0, n - 1);
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
System.out.print(arr[i][j] + " ");
}
System.out.println();
}
}
}
T3 完美平方数
题面
给定正整数n,找到最小数量的完美平方数(例如1, 4, 9, 16, ...),其总和为n。 例如,给定n = 12,返回3,因为12 = 4 + 4 + 4; 给定n = 13,返回2,因为13 = 4 + 9。
样例输入
12
样例输出
3
样例解释
见题面
思考与详解
这个题我第一直觉是写个递归搜索,然后就TLE
了,得了40分。大致思路就是首先找出所有小于n
的平方数,存在数组arr
中,然后从arr[ct-1]
开始搜索,记录当前和nowNum
和当前平方数的数量cnt
。代码如下:
import java.util.Scanner;
public class squareNumber {
public static int n, ct = 0;
public static int[] arr;
public static int ans;
public static void findSquareNumber() {
for (int i = 1; i <= n; i++) {
if (i * i <= n) {
arr[ct++] = i * i;
}
}
}
public static void func(int nowNum, int cnt, int flag) {
if (nowNum > n)
return;
else if (nowNum == n) {
ans = ans < cnt ? ans : cnt;
return;
} else {
for (int i = ct - 1; i >= flag; i--) {
func(nowNum + arr[i], cnt + 1, i);
}
}
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
n = in.nextInt();
in.close();
arr = new int[n + 100];
findSquareNumber();
ans = n + 100;
func(0, 0, 0);
System.out.println(ans);
}
}
百度了一下发现和leetcode 279是一样的题目,考察的知识点是动态规划。
这份官方题解给出了不错的思路,我就不再赘述,直接在下面给出本题的完整代码。
具体代码
import java.util.Scanner;
public class squareNumber {
public static int n, ct = 0;
public static int[] ans;
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
n = in.nextInt();
in.close();
ans = new int[n + 10];
for (int i = 1; i <= n; i++) {
int minn = Integer.MAX_VALUE;
for (int j = 1; j * j <= i; j++) {
minn = Math.min(minn, ans[i - j * j]);
}
ans[i] = minn + 1;
}
System.out.println(ans[n]);
}
}