一次由 Scanner(System.in) 引起的 TLE

莫名其妙 TLE

  继昨天一次由 System.out.println() 引起的 MLE&TLE后,今天随机到一道快速选择的题(P1923),又遇到相似的问题,写完快速排序后修改几行代码就得到快速选择的代码,本以为轻松解决问题,然后又莫名其妙的 TLE

原始代码:

public static void main(String[] args) throws IOException {
	Scanner in = new Scanner(System.in);// 标准输入
	int n = in.nextInt();
	int k = in.nextInt();
	int[] a = new int[n];
	
	for (int i = 0; i < n; ++i) {
		a[i] = in.nextInt();
	}
	
	quickSelect(a, 0, n-1, k);// 快速选择
	System.out.println(a[k]);// 标准输出
	in.close();
}

第一次尝试结果:
在这里插入图片描述

举一反三

  有了昨天 System.out.println() 造成 MLE 的经验,很容易就想到是因为使用 Scanner(System.in) 标准输入性能低下造成的 TLE,于是进行改进。

// 使用 StreamTokenizer 替代Scanner in = newScanner(System.in);
StreamTokenizer in =
  new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));

最终代码:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StreamTokenizer;
public class Main {
	// StreamTokenizer对象
	public static StreamTokenizer in = 
			new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
	// 由 Token获取 int
	public static int nextInt() throws IOException {
		in.nextToken();// 从输入流获取标记
		return (int)in.nval;// 转化
	}
	// 主函数
	public static void main(String[] args) throws IOException {
		int n = nextInt();// 自编写的读取整数函数
		int k = nextInt();
		int[] a = new int[n];
		for (int i = 0; i < n; ++i) {
			a[i] = nextInt();
		}
		quickSelect(a, 0, n-1, k);
		System.out.println(a[k]);
	}
}

最终结果:
在这里插入图片描述

总结

  • 使用 Scanner(System.in) 进行标准输出时,性能较差,不适合频繁调用。
  • 频繁输入调用使用 StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
  • 类 java.io.StreamTokenizer 可以获取输入流并将其分析为 Token(标记),使用 nextToken() 方法读取下一个标记。
  • 默认情况下,StreamTokenizer 认为下列内容是Token:字母数字除c和c++注释符号以外的其他符号
  • 使用 BufferedReader 创建 StreamTokenizer 对象以提高效率
  • 调用 nextToken() 方法从输入流中获取标记,调用 nextToken() 方法后,如果 Token 是字符串,可用 String s = st.sval 获取,如果是整数,可用 int x = (int)st.nval 获取。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值