You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何Scanner转换输入为二维char数组耗时过长?

优化Scanner读取超大网格输入的性能

针对你遇到的Scanner读取10000×10000网格时性能极差的问题,核心原因是Scanner默认的输入缓冲区过小,加上逐个charAt()的循环累积了大量方法调用开销。以下是针对必须使用Scanner的场景的优化方案:

优化方案

1. 增大Scanner的输入缓冲区

Scanner默认依赖的InputStreamReader缓冲区很小(通常是8KB),处理超大输入时会频繁触发IO操作,严重拖慢速度。用BufferedReader包装System.in并设置大缓冲区(比如1MB),再传给Scanner,能大幅减少IO次数。

2. 替换逐字符遍历为一次性转char数组

原代码中内层循环逐个调用charAt(j),1e8次的方法调用会带来可观的开销。直接使用String.toCharArray()一次性把整行转为char数组,再批量复制到二维数组中,能显著减少耗时。

优化后的代码

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Scanner;

public static void main(String[] args) {
    // 配置1MB大小的缓冲区,可根据需求调整(比如2MB)
    Scanner input = new Scanner(new BufferedReader(new InputStreamReader(System.in), 1024 * 1024));
    int rows = input.nextInt();
    int cols = input.nextInt();
    // 跳过nextInt()后遗留的换行符,避免读取空行
    input.skip("\n");

    char[][] seaCard = new char[rows][cols];

    for(int i = 0; i < rows; i++){
        String thisRow = input.nextLine();
        // 一次性转char数组,替代逐个charAt
        char[] rowChars = thisRow.toCharArray();
        // 批量复制到二维数组,比逐个赋值更高效
        System.arraycopy(rowChars, 0, seaCard[i], 0, cols);
    }
    input.close();
}

额外说明

  • 如果输入的每行没有空格,也可以用input.next()替代input.nextLine(),但核心优化还是缓冲区的配置,这对超大输入的性能提升最明显。
  • 10000×10000的网格需要占用约100MB内存(char占2字节),确保JVM的堆内存足够(可通过-Xmx256m参数调整)。

内容的提问来源于stack exchange,提问作者Jock

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 06:35:11