Блог пользователя Flatfoot

Автор Flatfoot, 12 лет назад, По-английски

Abstract

In the following I will describe how to read the input in Java. We will examine the Scanner class and then write our own class for faster input reading.

Using the Scanner class

We can read the input using the Scanner class:

import java.util.*;
 
public class Main{
   public static void main(String[] args) {
      // Use the Scanner class
      Scanner sc = new Scanner(System.in);  
      /*
      int n      = sc.nextInt();        // read input as integer
      long k     = sc.nextLong();       // read input as long
      double d   = sc.nextDouble();     // read input as double
      String str = sc.next();           // read input as String
      String s   = sc.nextLine();       // read whole line as String
      */
    }
}

Using the BufferedReader class

However, the Scanner class is slow and may cause a "timelimit exceeded". We can read the input faster with the BufferedReader class. The class "MyScanner" below uses a BufferedReader. The same method names as in the Scanner class have been chosen, e.g. to read the input as an integer we still can use nextInt().

import java.io.*;
import java.util.*;
 
 
public class Main{
   public static void main(String[] args) {
      MyScanner sc = new MyScanner();
      out = new PrintWriter(new BufferedOutputStream(System.out));
      
      // Start writing your solution here. -------------------------------------
   
      /*
      int n      = sc.nextInt();        // read input as integer
      long k     = sc.nextLong();       // read input as long
      double d   = sc.nextDouble();     // read input as double
      String str = sc.next();           // read input as String
      String s   = sc.nextLine();       // read whole line as String

      int result = 3*n;
      out.println(result);                    // print via PrintWriter
      */

      // Stop writing your solution here. -------------------------------------
      out.close();
   }

     

   //-----------PrintWriter for faster output---------------------------------
   public static PrintWriter out;
      
   //-----------MyScanner class for faster input----------
   public static class MyScanner {
      BufferedReader br;
      StringTokenizer st;
 
      public MyScanner() {
         br = new BufferedReader(new InputStreamReader(System.in));
      }
 
      String next() {
          while (st == null || !st.hasMoreElements()) {
              try {
                  st = new StringTokenizer(br.readLine());
              } catch (IOException e) {
                  e.printStackTrace();
              }
          }
          return st.nextToken();
      }
 
      int nextInt() {
          return Integer.parseInt(next());
      }
 
      long nextLong() {
          return Long.parseLong(next());
      }
 
      double nextDouble() {
          return Double.parseDouble(next());
      }
 
      String nextLine(){
          String str = "";
	  try {
	     str = br.readLine();
	  } catch (IOException e) {
	     e.printStackTrace();
	  }
	  return str;
      }

   }
   //--------------------------------------------------------
}

References

  1. FastScanner class used by xenoslash.

  2. Faster input for java – An article by James Brucker

  3. ReadLine in Java

If you know of a simpler/better method for input reading in Java, please post it below.

Edit 1 (30 August 2014)

I added PrintWriter for a faster output.

  • Проголосовать: нравится
  • +5
  • Проголосовать: не нравится

»
10 лет назад, # |
  Проголосовать: нравится -8 Проголосовать: не нравится

thanks a lot. could you explain the next() function.

i don't understand why while (st == null || !st.hasMoreElements()) especially !st.hasMoreElements() this part.

and how it is working ? like — int a = sc.nextInt(); int b = sc.nextInt();

if i gave input 1 2 then how can this do like a = 1 and b = 2 ? every time i call nextInt() then it call next() in a new form. so how it can split the output and put those in different variable ? thanks in advance.

»
10 лет назад, # |
  Проголосовать: нравится -6 Проголосовать: не нравится

Green tutorial? lol

»
10 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

great tutorial! Thx a lot for sharing! So are we allowed to use your code for contest? :-)

»
7 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

I could not understand the while loop part. Could anyone explain me that?

  • »
    »
    4 года назад, # ^ |
      Проголосовать: нравится +1 Проголосовать: не нравится

    Sorry for necroposting. But I thought it will be nice to have an explanation as I see 2 people asking for it.

    I know I am late. But this is for anyone else who might not understand it.

          String next() {
              // Do not process the insides of loop if there are tokens(parts of input in line) already present in st object
              // After reading the items from the stream, st will have tokens in it (in a scenario of empty lines, the loop will be executed until there are valid tokens).
              // If there is nothing left in the standard input, the loop will be terminated by an execption thrown by 'br.readLine()'
              while (st == null || !st.hasMoreElements()) {
                  try {
                      // If there are no tokens present, read a new line from input
                      st = new StringTokenizer(br.readLine()); 
                  } catch (IOException e) {
                      e.printStackTrace();
                  }
              }
              // If there were tokens already present in the st object, the while loop will not be executed and we will get the token from the earlier line read from the stream.
              // If there were no tokens present in the st object, they will be populated by the while loop above.
              return st.nextToken(); 
          }
    
    • »
      »
      »
      4 года назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится

      String next() throws IOException { while (!in.hasMoreTokens()) { in = new StringTokenizer(br.readLine()); } return in.nextToken(); } i think this one is better

»
6 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

Thanks a lot. You save my day.

»
4 года назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

please add for character ??