Java Scanner next() 和 nextLine() 的区别

引文

题目是这样的

字符串排序(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控制,直接获取下一行会是空的,存在问题。

  1. 先 nextInt 获取字符串个数
  2. 再用 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));
        }
}

猜你喜欢

转载自blog.csdn.net/qq_38666896/article/details/143452732