目录
一、选择题
二、倒置字符串
一、选择题
一、A 派生出子类 B , B 派生出子类 C ,并且在 java 源代码有如下声明:
1. A a0=new A();
2. A a1=new B();
3. A a2=new C();
问以下哪个说法是正确的(D)
A. 只有第一行能通过编译
B. 第1、2行能通过编译,但第3行编译出错
C. 第1、2、3行能通过编译,但第2、3行运行时出错
D. 第1行,第2行和第3行的声明都是正确的
答案:选D
因为B继承自A,C继承自B,也可以认为C继承了A。相当于你爸爸继承了你爷爷的一些特点,而你继承了你爸爸的特点,间接的你也继承了你爷爷的特点。
二、下面代码将输出什么内容:(B)
public class SystemUtil{ public static boolean isAdmin(String userId){ return userId.toLowerCase()=="admin"; } public static void main(String[] args){ System.out.println(isAdmin("Admin")); } }
A. true B. false C. 1 D. 编译错误
答案:B
字符串是一个引用类型,所以比较两个字符串是否相等需要使用equals方法,这里使用==比较,比较的是两个字符串的地址。
三、 阅读如下代码。 请问,对语句行 test.hello(). 描述正确的有(D)
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,不能正常运行
答案:D
这里是因为hello是属于类的方法,不能借助对象来调用,但是这个引用指向的对象为null,
所以这里test调用hello方法,是可以执行的,并没有借助对象来调用。
四、下列哪一种叙述是正确的(D)
A. abstract修饰符可修饰字段、方法和类
B. 抽象方法的body部分必须用一对大括号{ }包住
C. 声明抽象方法,大括号可有可无
D. 声明抽象方法不可写出大括号
答案:D
abstract可以修饰类和方法,但是不能修饰成员变量。
声明抽象方法,有访问限定修饰符、返回值类型、方法名,但是不能有方法体,也就是{}。
五、如下代码的执行结果是什么(B)
class Base { Base() { System.out.print("Base"); } } public class Alpha extends Base { public static void main( String[] args ) { new Alpha(); //调用父类无参的构造方法 new Base(); } }
A. Base B. BaseBase C. 编译失败 D. 代码运行但没有输出 E. 运行时抛出异常
答案B
因为在创建子类继承父类的时候,即使子类中没有写构造方法,在创建子类对象的时候,调用的无参构造方法,也会首先调用父类的构造方法,先执行父类的构造方法,然后再执行子类的构造方法。
六、如下代码的执行结果是什么(D)
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. 编译失败
答案:D
静态的变量只能再类中,或者静态方法、或者静态代码块中定义,不能再非静态的方法或者代码块中定义,因为静态的变量属于类,而给静态的方法和代码块通过实例化对象,就会属于某个对象。
二、倒置字符串
【解题思路】:这里我们将输入的字符串转换成字符数组,然后整体将字符数组中的元素逆置,然后再将每个单词进行逆置,这样就得到了一个逆置之后的字符串。
public class Main{
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
String str = scan.nextLine();
char[] ch = str.toCharArray();
int let = ch.length;
//将整体的字符串进行逆置
func(ch,0,let-1);
int i = 0;
while(i < let){
int j = i;//i用来遍历数组中的单词
//当j小于数组长度并且j指向的位置不是空格,则向前挪动一位。
while(j < let && ch[j]!= ' '){
j++;
}
//当j没有走到数组末尾之后,则对空格之前的单词进行逆置
if(j < let){
func(ch,i,j-1);
i = j+1;
}else{
//如果j走到最后数组最后一个元素之后,则表示这个数组中每个单词已经逆置完了,将i和j放在同一个位置,用i作为循环结束条件。
func(ch,i,j-1);
i = j;
}
}
String string = new String(ch);
System.out.println(string);
}
public static void func(char[] array,int start,int end){
while(end>start){
char tmp = array[start];
array[start] = array[end];
array[end] = tmp;
//两个指针移动到下一个需要交换的位置,进行下一组交换。
start++;
end--;
}
}
}
三、排序子序列
牛牛定义排序子序列为一个数组中一段连续的子序列,并且这段子序列是非递增或者非递减排序的。牛牛有一个长度为n的整数数组A,他现在有一个任务是把数组A分为若干段排序子序列,牛牛想知道它最少可以把这个数组分为几段排序子序列。
如阳历所示,牛牛可以把数组A划分为[1,2,3]和[2,2,1]两个排序子序列,至少需要划分2个排序子序列,所以输出2.
输入描述:输入的第一行为一个正整数n(1 ≤ n ≤ 10^5),第二行包括n个帧数A_i(1 ≤ A_i ≤ 10^9),表示数组A的每个数字。
输出描述:输出一个整数表示牛牛可以将A最少划分为多少段排序子序列
示例
输入6
1 2 3 2 2 1
输出 2
题目分析
递增排列:1,2,3,4,5;也就是a[ i ] < a[ i+1 ]
递减排列:9,8,7,6,5;也就是a[ i ] > a[ i+1 ]
非递减排列:1,2,2,3,3,5,6;也就是a[ i ] <= a[ i+1 ]
非递增序列:9,8,7,5,5,3,2;也就是a[ i ] >= a[ i+1 ]
- 非递增和非递减排列整体还是呈现递减或者递增,但是中间存在相同的数。
- 上述题目表示的意思为,你输入的一组数字,可以按照非递增或者非递减的方式分为几组。你输入的这组数字,可能存在连续几个数字是非递增,这几个数字之后,又存在一些数字是连续非递减的。
✨当我们定义一个变量i遍历你输入的这个数组,存在三种情况
- i遍历到的数字,比i+1位置的数字小,
- i遍历到的数字,比i+1位置的数字大,
- i遍历到的数字,与i+1位置的相等。
代码示例
public class Main{
public static void main(String[] args) {
Scanner scan =new Scanner(System.in);
int n = scan.nextInt();//定义的输入元素的个数
int[] arr = new int[n+1];//这里给数组定义的长度比输入的大1,是因为防止遍历数组进行比较的时候,出现数组越界。
for (int i = 0; i < n; i++) {
arr[i] = scan.nextInt();
}
int count = 0;//用来记录划分的子序列的个数
int i = 0;//使用i遍历数组
//这里使用循环,因为i没向前做一步,都需要判断是否到元素的末尾,并且判断是三种情况中的哪一个
while(i < n){
if(arr[i] < arr[i+1]){
//i下标的值比i+1小
while(i < n && arr[i] < arr[i+1]){
//有可能存在一些值连续情况下都是i下标的值比i+1的小,将这种情况的一组数据遍历完就需要使用一个变量记录一下,
//这就是数组划分的一个子序列。
i++;
}
count++;
//这里使用i++,例如 123221,当i在3的位置时,没有满足if条件,所以3之前包括3,被划分为一个子序列,就需要i在向前走一位。
i++;
}else if(arr[i] == arr[i+1]){
//i下标的值和i+1的值相等
i++;
}else{
//i下标的值比i+1的值大
while(i < n && arr[i] > arr[i+1]){
//也有可能出现一组连续的数字i位置的值比i+1位置的值大,这种情况的一组数据遍历完成之后,就需要记录一下。
//这就是 数组划分的有一个子序列
i++;
}
count++;
i++;
}
}
System.out.println(count);
}
}
图解代码中对数组越界的处理