做算法题使用Java Scanner内存占用超范围问题
2023-05-28

引言

最近在看浙大陈越老师的数据结构课程,第一周做了一道求最大子列和问题。

image

image-1654929391940

通过Scanner输入数据,提交之后100000个数据时内存超限了,反复看了一下写的算法发现没啥问题,我就怀疑是Scanner的问题,搜了一下怎么减少占用的内存,发现需要换一个类来输入,下面记录一下解决的办法。

这是原来的代码

import java.util.Scanner;
class Main{
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        int K = sc.nextInt();
        int sum = 0;
        int maxSum = 0;
        for(int i=0; i<K;i++){
             sum += sc.nextInt();
            if(sum<0){
                sum = 0;
            }
            if(sum > maxSum){
                maxSum = sum;
            }
        }
        System.out.println(maxSum);
        sc.close();
    }
}

使用BufferReader 替换 Scanner

直接上代码

import java.util.StringTokenizer;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
class Main{
    public static void main(String[] args) throws IOException{
    	// 创建BufferedReader对象,使用InputStreamReader将字节流转换为字符流
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        // 读取第一行并转为整数
        int K = Integer.parseInt(reader.readLine());
        int sum = 0;
        int maxSum = 0;
        // 读入第二行,并创建一个StringTokenizer 用来分隔字符串
        StringTokenizer sc = new StringTokenizer(reader.readLine());
        for(int i=0; i<K;i++){
        	 // 读取并转换为整数
             sum += Integer.parseInt(sc.nextToken());
            if(sum<0){
                sum = 0;
            }
            if(sum > maxSum){
                maxSum = sum;
            }
        }
        System.out.println(maxSum);
        reader.close();
    }
}

效果

image-1654930902954

BufferedReader可以用来读取文件或者接收来自键盘(控制台)的信息。它比Scanner更加快捷,他直接读取字符流,而Scanner 会使用正则来解析数据。 注意:BufferedReader构造方法接收的是字符流 需要使用InputStreamReader 将字节输入流 System.in 变为字符流. 同时需要抛一下IOException异常。

BufferedReader 通过 readLine() 来获取一行数据,可以使用StringTokenizer 来将读入的数据分隔。java 默认的分隔符是空格("")制表符(\t)换行符(\n)回车符(\r)nextToken() 方法用来返回下一个字符串

也可以换成C

image-1654931510809