引文
题目是这样的
字符串排序(1)
对输入的字符串进行排序后输出
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 256M,其他语言512M
输入描述:
输入有两行,第一行n
第二行是n个字符串,字符串之间用空格隔开
输出描述:
输出一行排序后的字符串,空格隔开,无结尾空格
示例1
输入例子:
5
c d a bb e
输出例子:
a bb c d e
问题
报错1
本来是 nextLine 获取输入的,没用上第一行长度n控制,直接获取下一行会是空的,存在问题。
- 先 nextInt 获取字符串个数
- 再用 nextLine 获取下一行数据,用空格隔开的字符串,得到一个数组
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int size = in.nextInt();
String[] strs = in.nextLine().split(" ");
System.out.println(Arrays.toString(strs)); //空
}
直接将数据打印也是是空的
int size = in.nextInt();
System.out.println("size = " + size + in.nextLine());
那么next() 和 nextLine() 有什么区别呢?为什么上面不能用nextLine获取一行呢??
报错2
while(in.hasNextLine()) {
int size = in.nextInt();
String[] strs = in.nextLine().split(" ");
System.out.println("strs = " + Arrays.toString(strs));
Arrays.sort(strs);
System.out.println(String.join(" ", strs));
}
执行出错的原因是用 hasNextLine 判断,但是用 nextInt 获取,在文章讲过其匹配性
解决方案:只要将获取方式修改,并使用字符串整型转换即可
while(in.hasNextLine()) {
int size = Integer.parseInt(in.nextLine()); //用 line 并且数据类型转换
String[] strs = in.nextLine().split(" ");
System.out.println("strs = " + Arrays.toString(strs));
Arrays.sort(strs);
System.out.println(String.join(" ", strs));
}
可行案例
next()
接着换成控制大小,用 next 获取输入,需要注意数字下标。
int size = in.nextInt();
String[] strs = new String[size];
for (int i = 0; i < size; i++) {
strs[i] = in.next();
}
//可以用数组打印输出,否则只能看到对象的虚拟地址
System.out.println(Arrays.toString(strs));
//将字符串排序
Arrays.sort(strs);
//将结果转成字符串,用空格间隔。
String result = String.join(" ", strs);
System.out.println(result);
nextLine()
其实这种方法也是可行的,关键在于先判断(应该可以消耗一个回车空格)
如下debug代码和结果可以看到,需要两个nextLine才能获取到下一行:
Scanner in = new Scanner(System.in);
int size = in.nextInt();
int i = 0;
while(in.hasNextLine()) {
System.out.println("size = " + size + " " + i + in.nextLine());
i++;
}
执行结果:
当 i=1 即循环第二次的时候才会正确获取到多个字符串,因为 hasNextLine() 会缓冲区从头开始遍历吗?即首先获取的数据长度5也会重新开始遍历。
所以如果是使用nextLine的话, while 循环应该放在最外层控制输入和读取。
正解
两者的运行时间和内存占用大小都差不多,不过直接用Line控制输入直接操作的略优一点。
使用 next() 版本
import java.util.Arrays;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int size = in.nextInt();
String[] strs = new String[size];
for (int i = 0; i < size; i++) {
strs[i] = in.next();
}
//System.out.println(Arrays.toString(strs));
Arrays.sort(strs);
//将结果转成字符串,用空格间隔。
String result = String.join(" ", strs);
System.out.println(result);
}
使用 nextLine() 的版本
import java.util.Arrays;
import java.util.Scanner;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
while(in.hasNextLine()) {
int size = Integer.parseInt(in.nextLine());
String[] strs = in.nextLine().split(" ");
//System.out.println("strs = " + Arrays.toString(strs));
Arrays.sort(strs);
System.out.println(String.join(" ", strs));
}
}