当前位置:   article > 正文

Java快读模板----配详细解析

Java快读模板----配详细解析

   引言

        对于很多走java后端的小伙伴都避免不了用java去写算法题,而对于像力扣这种刷题网站不需要我们处理输入输出,我们就会写的很舒服,但是如果是洛谷,牛客,cf,各大高校的oj之类的刷题网站需要我们自己处理输入输出,我们就会意识到java那个Scanner类读取数据是非常慢的(当然java什么都比c++慢),我这里的慢是指可能读取数据就把那一秒时限给跑完了。

        所以这里我给大家分享一个保姆级别的java快读类,让你就像在用scanner一样得心应手,但读入又快了不少,以至于不影响大佬你ac题的速度。下面进入正文。

        我这里先贴模板了,再给出解释,因为我觉得可能很多人都是为了模板来的,hhh。

        可以直接把下面这段代码贴你代码下面,然后就可以开始成为无情的刷题机器了。方法名和作用都和你之前用Scanner类是一样的。

  1. class read {
  2. BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
  3. StreamTokenizer st = new StreamTokenizer(bf);
  4. String next() {
  5. return st.sval;
  6. }
  7. String nextLine() throws IOException {
  8. return bf.readLine();
  9. }
  10. int nextInt() throws IOException {
  11. st.nextToken();
  12. return (int) st.nval;
  13. }
  14. long nextLong() throws IOException {
  15. st.nextToken();
  16. return (long) st.nval;
  17. }
  18. double nextDouble() throws IOException {
  19. st.nextToken();
  20. return st.nval;
  21. }
  22. }

        相信看到这里的都是不知道为什么Scanner类慢,以及这个快读类快的同学了吧,下面我就给大家详细解释一下

        首先我们来解释一下为什么Scanner类慢:

        因为Scanner类的输入的信息都是放在一个文件里,Scanner每次调用next()都需要访问IO设备,而且每次调用都只会取出去一个数,所以这样的速度就非常的慢。

        而为什么我们这个read类就快了,细心的你在看上面的代码是一定会发现,其实我们read类主要就是两个对象在起作用,一个是BufferedReader,另一个是StreamTokenizer。

        首先是BufferedReader,详细大家对他都不陌生,在学习io流时就对他有所了解了,它读取数据时,会先把放在文件中的数据全部放到内存缓冲区去,BufferedReader.next()的时候就直接到内存缓冲区拿数据。

        接着我们来介绍一下这个类StreamTokenizer。StreamTokenizer这类用于将输入流(比如文件或者字符串)分解为词法单元(tokens)。它可以识别不同类型的词法单元,如数字、字符串、标识符、运算符等,并将它们以相应的类型进行分类。在处理文本文件或解析简单的文本格式时,StreamTokenizer非常有用。也就是说StreamTokenizer类可以帮我们帮我转换当前读入是数字还是字符。

      下面我就带大家来实践一下这个read类。就拿下面这道题来举例吧[NOIP2016 普及组] 海港 - 洛谷icon-default.png?t=N7T8https://www.luogu.com.cn/problem/P2058        补充一句,一般对于输入大于十的五次方的题目,基本上用Scanner就过不了,但是其实我们一直用快读类就好了,直接忘掉Scanner吧。

        这道题并不难,相信大家都会吧,同样我也不是来讲算法的,如果不会可以评论区留言,我也可以给你仔细讲一下。

        对于这道题如果我们用Scanner来读取数据那代码就是下面这样。

  1. import java.io.BufferedReader;
  2. import java.io.IOException;
  3. import java.io.InputStreamReader;
  4. import java.io.StreamTokenizer;
  5. import java.util.*;
  6. public class Main {
  7. private static int[] personNum = new int[1000005];
  8. public static void main(String[] args) {
  9. Scanner sc = new Scanner(System.in);
  10. int n = sc.nextInt();
  11. int ans = 0;
  12. Queue<person> queue = new LinkedList<>();
  13. for (int i = 0; i < n; i++) {
  14. int t = sc.nextInt();
  15. int k = sc.nextInt();
  16. List<Integer> list = new ArrayList<>();
  17. for (int j = 0; j < k; j++) {
  18. int x = sc.nextInt();
  19. list.add(x);
  20. personNum[x]++;
  21. if (personNum[x] == 1) ans++;
  22. }
  23. person p = new person(t, list);
  24. while (!queue.isEmpty() && t - queue.peek().t >= 86400) {
  25. for (Integer count : queue.peek().list) {
  26. personNum[count]--;
  27. if (personNum[count] == 0) ans--;
  28. }
  29. queue.poll();
  30. }
  31. queue.add(p);
  32. System.out.println(ans);
  33. }
  34. }
  35. }
  36. class person {
  37. public int t;
  38. public List<Integer> list;
  39. public person(int t, List<Integer> list) {
  40. this.t = t;
  41. this.list = list;
  42. }
  43. }

        对比一下数据样例,我们当前这个算法的时间复杂度是绝对没有超的。但是当我们信心满满提交后,就会得到好几个mle,就好比下面这样。

        但是如果我们用上面的read快读类,代码就像下面这样,其实差不了多少,这种快读模板,直接cv上去就好了。

  1. import java.io.BufferedReader;
  2. import java.io.IOException;
  3. import java.io.InputStreamReader;
  4. import java.io.StreamTokenizer;
  5. import java.util.ArrayList;
  6. import java.util.LinkedList;
  7. import java.util.List;
  8. import java.util.Queue;
  9. public class Main {
  10. private static int[] personNum = new int[1000005];
  11. public static void main(String[] args) throws Exception {
  12. read rf = new read();
  13. int n = rf.nextInt();
  14. int ans = 0;
  15. Queue<person> queue = new LinkedList<>();
  16. for (int i = 0; i < n; i++) {
  17. String[] split = rf.nextLine().split(" ");
  18. int t = Integer.parseInt(split[0]);
  19. int k = Integer.parseInt(split[1]);
  20. List<Integer> list = new ArrayList<>();
  21. for (int j = 0; j < k; j++) {
  22. int x = Integer.parseInt(split[j + 2]);
  23. list.add(x);
  24. personNum[x]++;
  25. if (personNum[x] == 1) ans++;
  26. }
  27. person p = new person(t, list);
  28. while (!queue.isEmpty() && t - queue.peek().t >= 86400) {
  29. for (Integer count : queue.peek().list) {
  30. personNum[count]--;
  31. if (personNum[count] == 0) ans--;
  32. }
  33. queue.poll();
  34. }
  35. queue.add(p);
  36. System.out.println(ans);
  37. }
  38. }
  39. }
  40. class person {
  41. public int t;
  42. public List<Integer> list;
  43. public person(int t, List<Integer> list) {
  44. this.t = t;
  45. this.list = list;
  46. }
  47. }
  48. class read {
  49. BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
  50. StreamTokenizer st = new StreamTokenizer(bf);
  51. String next() {
  52. return st.sval;
  53. }
  54. String nextLine() throws IOException {
  55. return bf.readLine();
  56. }
  57. int nextInt() throws IOException {
  58. st.nextToken();
  59. return (int) st.nval;
  60. }
  61. long nextLong() throws IOException {
  62. st.nextToken();
  63. return (long) st.nval;
  64. }
  65. double nextDouble() throws IOException {
  66. st.nextToken();
  67. return st.nval;
  68. }
  69. }

               然后这时我们再来提交,就会喜提ac,

                最后谢谢大家看到最后,制作不易,如果觉得还不错,可以三连支持一下。 

                关关难过关关过。

本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/空白诗007/article/detail/856159
推荐阅读
相关标签
  

闽ICP备14008679号