努力经营当下,直至未来明朗!
文章目录
- 一、选择
- 二、 编程
- 1. 排序子序列
- 2. 倒置字符串
- 答案
- 1. 选择
- 2. 编程
普通小孩也要热爱生活!
一、选择
- 阅读如下代码。 请问,对语句行 test.hello(). 描述正确的有()
package NowCoder;
class Test {
public static void hello() {
System.out.println("hello");
}
}
public class MyApplication {
public static void main(String[] args) {
// TODO Auto-generated method stub
Test test=null;
test.hello();
}
}
A 能编译通过,并正确运行
B 因为使用了未初始化的变量,所以不能编译通过
C 以错误的方式访问了静态方法
D 能编译通过,但因变量为null,不能正常运行
-
在使用super和this关键字时,以下描述正确的是()
A 在子类构造方法中使用super()显示调用父类的构造方法,super()必须写在子类构造方法的第一行,否则编译不通过
B super()和this()不一定要放在构造方法内第一行
C this()和super()可以同时出现在一个构造函数中
D this()和super()可以在static环境中使用,包括static方法和static语句块 -
如下代码的输出结果是什么?
public class Test {
public int aMethod(){
static int i = 0;
i++;
return i;
}
public static void main(String args[]){
Test test = new Test();
test.aMethod();
int j = test.aMethod();
System.out.println(j);
}
}
A 0
B 1
C 2
D 编译失败
-
下列哪一种叙述是正确的()
A abstract修饰符可修饰字段、方法和类
B 抽象方法的body部分必须用一对大括号{ }包住
C 声明抽象方法,大括号可有可无
D 声明抽象方法不可写出大括号 -
下列说法正确的有:()
A class中的constructor不可省略
B constructor必须与class同名,但方法不能与class同名
C constructor在一个对象被new 时执行
D 一个class只能定义一个constructor -
选项中哪一行代码可以替换 //add code here 而不产生编译错误()
public abstract class MyClass {
public int constInt = 5;
//add code here
public void method() {
}
}
A public abstract void method(int a);
B consInt=constInt+5;
C public int method();
D public abstract void anotherMethod(){}
二、 编程
1. 排序子序列
排列子序列
牛牛定义排序子序列为一个数组中一段连续的子序列,并且这段子序列是非递增或者非递减排序的。牛牛有一个长度为n的整数数组A,他现在有一个任务是把数组A分为若干段排序子序列,牛牛想知道他最少可以把这个数组分为几段排序子序列。
2. 倒置字符串
倒置字符串
将一句话的单词进行倒置,标点不倒置。
比如 I like beijing. 经过函数后变为:beijing. like I
答案
1. 选择
- ① 因为Test类的hello方法是静态的,所以是属于类的,当实例化该类的时候,静态会被优先加载而且只加载一次,所以不受实例化new Test();影响,只要是使用到了Test类,都会加载静态hello方法!
② 另外,在其他类的静态方法中也是可以调用公开的静态方法,此题hello方法是使用public修饰的,所以在MyApplication中调用hello也是可以的。
③ 总结:即使Test test=null;这里也会加载静态方法,所以test数据中包含Test类的初始化数据。
④ 如果不是静态方法就会抛出空指针异常。
故:选A
-
① 调用super()必须写在子类构造方法的第一行,否则编译不通过。每个子类构造方法的第一条语句,都是隐式地调用super(),如果父类没有这种形式的构造方法,那么在编译的时候就会报错。
② super()和this()类似,区别是:super()从子类中调用父类的构造方法,this()在同一类内调用其它方法(this是当前对象的引用)。
③ super()和this()均需放在构造方法内第一行。
④ 尽管可以用this调用一个构造器,但却不能调用两个。
⑤ this和super不能同时出现在一个构造函数里面。因为this必然会调用其它的构造函数,其它的构造函数必然也会有super语句的存在,所以在同一个构造函数里面有相同的语句,就失去了语句的意义,编译器也不会通过。
⑥ this()和super()都指的是对象,所以,均不可以在static环境中使用。包括:static变量,static方法,static语句块。
⑦ 从本质上讲,this是一个指向本对象的指针, 然而super是一个Java关键字。
(具体参考:super和this区别) -
Java中静态变量只能在类主体中定义,不能在方法中定义。 静态变量属于类所有而不属于方法。
故:选D
- ① abstract只能修饰方法、类,不能修饰字段。
② 抽象方法不能被private、static、final等修饰。
③ 有抽象方法的类一定是抽象类。但是抽象类中不一定都是抽象方法,也可以全是具体方法。
(具体可以参考:abstract详细)
故:选D
- ① 方法可以和类同名,只不过构造方法没有返回值,而方法是有返回值的。
② constructor:与类同名 、一个类可有多个 、无返回值 、伴随new操作一起调用 、默认有无参构造方法
故:选C
- ① A是抽象方法,抽象类可以包含抽象方法,也可以不包含,实现重载。
② B 在类中不能constInt = constInt + 5,但是在方法中可以。
③ C 返回值不能作为重载的依据。重载:同名不同参,与返回值无关!
④ D 有方法体的不能作为抽象函数,抽象函数没有方法体{}。
故:选A
- ① 接口中每一个方法都是public的抽象方法, 即接口中的方法会被隐式的指定为 public abstract(只能是 public abstract,其他修饰符都会报错)
② 所以:重写接口的方法修饰符只能是public(因为默认的接口方法的修饰符就是public,继承要>=)
③ 接口中的方法是不能在接口中实现的,只能由实现接口的类来实现
④ 接口中可以含有变量,但是接口中的变量会被隐式的指定为 public static final 变量(注:必须赋初值;且后续不能被修改,具有final属性)
(详细参考:接口)
2. 编程
- 排序子序列
1)理解:
① 非递增:a[i] >= a[i+1]
② 非递减:a[i] <= a[i+1]
2)思路:
① 首先进行判断:如果是递增,就继续往后判断(循环,条件为非递减),直到遇到递减的情况,也就是a[i] < a[i+1],此时就count++,且i++;然后开始进行下一轮判断;
② 递减也是同样思路
③ 相等就只是进行i++,不用进行任何操作
④ 这里要注意越界问题:所以多增加一个长度,将最后一个元素设为0.此时,并不会影响判断,只是为了辅助最后一个是单独的情况!
3)注意:
① 越界问题
② 多层循环
③ 辅助最后一个单独的情况:数组长度+1 ,同时<n也保证了数组的不越界(i+1)
4)代码:
// 排列子序列(个数min)
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
// 为了避免数组越界 + 辅助最后一个元素单独的情况:
// 数组长度+1
int[] array = new int[n+1];
for (int i = 0; i < n; i++) {
array[i] = in.nextInt();
}
// 最后一个元素就是默认值0
int count = 0;
// 开始进行分组
for (int i = 0; i < n; i++) { // 不会越界,后面还有一个n下标0值(也就是说i+1不会越界
// for循环也可以改用 while(i<n)
if(array[i] < array[i+1]) {
// 递增:往后也要是非递减(循环)
while(i<n && array[i] <= array[i+1]) {
i++; // 一直往后走
}
// 来到这儿:说明遇到了递减的情况,也就是array[i] > array[i+1]
// 下一次是要从i+1开始判断(但是这里不用写,因为for循环中已经写了i++条件)
count++;
//i++;
} else if(array[i] > array[i+1]) {
// 递减:此时往后的也要是非递增
while(i<n && array[i] >= array[i+1]) {
i++; // 一直往后走
}
count++;
//i++;
} else {
// 相等,不进行任何操作,往后挪动就行
// i++;
}
}
System.out.println(count);
}
}
- 倒置字符串
1)思路:
① 其实本题就是需要以单词为单位进行倒置。
② 方法:先逆置整个字符串,然后遍历整个字符串,找出每个单词,对单词进行逆置。
③ 注意:逆置过程转换为数组来进行。
④ 细节:在找单词时,要记录下单词的始末位置方便进行逆置;使用循环找单词。
⑤ 使用了双层循环。
2)代码:
import java.util.Scanner;
// 倒置字符串
// 先整个字符串逆置,然后再对单词进行逆置
public class Main {
// 逆置函数
public static void reverse(char[] array,int start,int end) {
while (start < end) {
char tmp = array[start];
array[start] = array[end];
array[end] = tmp;
start++;
end--;
}
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String str = in.nextLine();
char[] ch = str.toCharArray(); // 将字符串转为数组形式
int len = ch.length;
// 1. 整体进行逆置
reverse(ch,0,len-1);
// 2. 再次遍历寻找单词进行逆置
int i = 0;
while (i < len){
// 要记录每个单词的始末位置:要对每个单词进行逆置
// 单词之间的分割:空格
int j = i; //每个单词的起始位置
// 使用循环找每个单词
while (j<len && ch[j]!=' ') {
j++;
}
// 出来说明此时遇到空格 or ==length(也就是到最后)
// 所以进行判断
if(j < len) {
// 说明是遇到空格:j的位置是空格
// 逆置单词 + 更新下一个单词的i值(起始位置)
reverse(ch,i,j-1);
i = j+1;
} else {
// 说明是走到了最后
// 同样逆置单词 + 更新i值
reverse(ch,i,j-1);
i = j;
}
}
// 将数组有转为字符串
String new_str = new String(ch);
System.out.println(new_str);
}
}