当前位置: 首页 > news >正文

ACM模式用Scanner和System.out超时的解决方案和原理

Hi~!这里是奋斗的明志,很荣幸您能阅读我的文章,诚请评论指点,欢迎欢迎 ~~
🌱🌱个人主页:奋斗的明志
🌱🌱所属专栏:笔试强训

📚本系列文章为个人学习笔记,在这里撰写成文一为巩固知识,二为展示我的学习过程及理解。文笔、排版拙劣,望见谅。

在这里插入图片描述

笔试强训

  • 一、ACM模式下(Java)
    • 1、为什么 Scanner 在输入的时候会慢
    • 2、为什么 System.out 在输出的时候会慢
  • 二、利用自定义快读模版(Java)
  • 三、Java StringTokenizer 类使用方法
    • 1、案例一
    • 2、案例二
  • 四、BufferedReader
    • 1、为什么要用while循环
    • 2、快速写

一、ACM模式下(Java)

  • 在ACM模式环境下,输入和输出的时候会先将输入输出的东西放在一个文件里面,这个文件可以称为IO设备
    在这里插入图片描述

1、为什么 Scanner 在输入的时候会慢

在这里插入图片描述
new 一个 Scanner ,在 Scanner 里面调用 next 的时候,程序会直接访问 IO 设备。在调用一个 next() 的时候,只会在 IO 设备中拿出一个数,再将这个数返回程序

调用一个 next() 就会访问一次 IO 设备,程序访问 IO 设备的速度特别慢。所以当输入的数据量很大的时候,就会多次访问这个 IO 设备,所以就会超时。

2、为什么 System.out 在输出的时候会慢

Scanner 读取数据一样。当输出数据的时候,也是将数据一个一个拿到 IO 设备中。由于程序访问 IO 设备的速度特别慢,所以只要数据量稍微多一些,就会超时

二、利用自定义快读模版(Java)

Java 在处理 IO 的时候,有两套标准:
字节流(System.in)
字符流(带 Reader 或者 Writer)

import java.util.*;
import java.io.*;public class Main
{public static PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));public static Read in = new Read();public static void main(String[] args) throws IOException{// 写代码out.close();}
}class Read // 自定义快速读入
{// 字符串分割器StringTokenizer st = new StringTokenizer("");// 缓冲读取器BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));// 核心方法:获取下一个输入片段String next() throws IOException {while(!st.hasMoreTokens()){st = new StringTokenizer(bf.readLine());}return st.nextToken();}String nextLine() throws IOException {return bf.readLine();}int nextInt() throws IOException {return Integer.parseInt(next());}long nextLong() throws IOException {return Long.parseLong(next());}double nextDouble() throws IOException {return Double.parseDouble(next());}
}

三、Java StringTokenizer 类使用方法

Java StringTokenizer 属于 java.util 包,用于分隔字符串。

StringTokenizer 构造方法:

  • StringTokenizer(String str) :构造一个用来解析 str 的 StringTokenizer 对象。java 默认的分隔符是空格(“”)、制表符(\t)、换行符(\n)、回车符(\r)。
  • StringTokenizer(String str, String delim) :构造一个用来解析 str 的 StringTokenizer 对象,并提供一个指定的分隔符。
  • StringTokenizer(String str, String delim, boolean returnDelims) :构造一个用来解析 str 的 StringTokenizer 对象,并提供一个指定的分隔符,同时,指定是否返回分隔符。

StringTokenizer 常用方法:

  • int countTokens():返回nextToken方法被调用的次数。
  • boolean hasMoreTokens():返回是否还有分隔符。
  • boolean hasMoreElements():判断枚举 (Enumeration) 对象中是否还有数据。
  • String nextToken():返回从当前位置到下一个分隔符的字符串。
  • Object nextElement():返回枚举 (Enumeration) 对象的下一个元素。
  • String nextToken(String delim):与 nextToken 类似,以指定的分隔符返回结果。

1、案例一

import java.util.*;public class Main 
{ public static void main(String[] args){ String str = "runoob,google,taobao,facebook,zhihu";// 以 , 号为分隔符来分隔字符串StringTokenizer st=new StringTokenizer(str,",");while(st.hasMoreTokens()) { System.out.println(st.nextToken());}}
}输出结果为:
runoob
google
taobao
facebook
zhihu

2、案例二

import java.util.*;public class Main
{public static void main(String args[]){System.out.println("使用第一种构造函数:");StringTokenizer st1 = new StringTokenizer("Hello Runoob How are you", " ");while (st1.hasMoreTokens())System.out.println(st1.nextToken());System.out.println("使用第二种构造函数:");StringTokenizer st2 = new StringTokenizer("JAVA : Code : String", " :");while (st2.hasMoreTokens())System.out.println(st2.nextToken());System.out.println("使用第三种构造函数:");StringTokenizer st3 = new StringTokenizer("JAVA : Code : String", " :",  true);while (st3.hasMoreTokens())System.out.println(st3.nextToken());}
}使用第一种构造函数:
Hello
Runoob
How
are
you
使用第二种构造函数:
JAVA
Code
String
使用第三种构造函数:
JAVA:Code:String

在这里插入图片描述

在这里插入图片描述

四、BufferedReader

它是一个带内存缓冲区的字符流。将要读取数据的时候,先将 IO 设备里面的数据一次性放到这个"内存缓冲区中"。然后 BufferedReader 再调用 next() 的时候,就是直接在内存缓冲区里面拿数据的

这对比 Scanner 调用 next 之后,一次一次地重复在 IO 设备中读取数据来说,BufferedReader 在调用 next 的时候,只需要读取一次内存缓冲区,就能读取到所有数据。

直接从内存中拿数据,肯定是比访问 IO 设备要快得多的

1、为什么要用while循环

因为有一些输入输出的题目,输入的数据不止只有一行,当把第一行的数据一个一个裁完之后,你是要读取下一行数据的。所以需要一个 while 循环判断,当后面没有数据了,就重新再读入一行,然后再返回新读入的一行的字符串
BufferedReader 相较于 System.in 快,就是因为他带了一个缓冲区。先把文件里面的数据刷新到缓冲区里面,然后在缓冲区里面拿一行一行的数据。随后通过 StringTokenizer 将读取的一行一行数据(bf.readLine())一个个地进行裁剪工作。当后面还有的行时候,就一个一个的裁;当后面没有行的时候,就再重新读一行,一个一个地裁

2、快速写

new BufferedWriter(new OutputStreamWriter(System.in))

这里是把字符流转换为字节流

此处的 BufferedReader 是在输出的时候,不直接将数据从 IO 设备输出到程序,而是先将数据输出到内存缓冲区中,然后程序在内存缓冲区中直接读取数据(与输入原理一致)

PrintWriter 其实 BufferedWriter 已经满足我们的需求了,为什么还要套一层 PrintWriter 呢?

因为 BufferWriter 的输出方式不好写,而 PrintWriter 的输出方式和 System.out 是完全一样的(使用方式完全一样)

在这里插入图片描述

在这里插入图片描述

http://www.xdnf.cn/news/482545.html

相关文章:

  • 锐捷交换机STP环路日志信息解读
  • NLG的可解释性困局:可视化工具Captum在生成模型中的应用
  • 【学习心得】Jupyter 如何在conda的base环境中其他虚拟环境内核
  • Spring Boot三层架构设计模式
  • 风控贷中策略笔记
  • CSS:颜色的三种表示方式
  • 汽车装配又又又升级,ethernetip转profinet进阶跃迁指南
  • mongodb用systemctl启动code=killed, signal=ABRT
  • 关于 Web安全:1. Web 安全基础知识
  • 全球泳装与沙滩装市场深度洞察:从功能性需求到可持续时尚的蜕变(2025-2031)
  • Elasticsearch-kibana索引操作
  • 归并排序:分治思想的优雅实现
  • 电子电路:被动电子元件都有哪些?
  • AI神经网络降噪算法在语音通话产品中的应用优势与前景分析
  • 轨迹误差评估完整流程总结(使用 evo 工具)
  • 【踩坑记录】transformers 加载 checkpoint 继续训练
  • 微信小程序:封装表格组件并引用
  • 多模态大语言模型arxiv论文略读(七十九)
  • 每日算法刷题Day8 5.15:leetcode滑动窗口4道题,用时1h
  • COMSOL随机参数化表面流体流动模拟
  • linux 服务器安装jira-8.22.0和confluence-8.5.21
  • rinetd 实现通过访问主机访问虚拟机中的业务,调试虚拟机内的java进程
  • Qwen2.5-VL模型sft微调和使用vllm部署
  • TLS 1.3黑魔法:从协议破解到极致性能调优
  • 系统提示学习(System Prompt Learning)在医学编程中的初步分析与探索
  • 在Linux服务器上部署Jupyter Notebook并实现ssh无密码远程访问
  • 【Kubernetes】单Master集群部署(第二篇)
  • 15 C 语言字符类型详解:转义字符、格式化输出、字符类型本质、ASCII 码编程实战、最值宏汇总
  • 深度学习笔记23-LSTM实现火灾预测(Tensorflow)
  • Stratix 10 FPGA DDR4 选型