E/S rápida en Java en programación competitiva

El uso de Java en la programación competitiva no es algo que mucha gente sugiera solo por su entrada y salida lentas, y bueno, de hecho, es lento.

En este artículo, hemos discutido algunas formas de sortear la dificultad y cambiar el veredicto de TLE a (en la mayoría de los casos) AC.

Ejemplo:

Input:
7 3
1
51
966369
7
9
999996
11
Output: 
4

1. Clase de escáner (fácil, menos tipeo, pero no se recomienda muy lento, consulte esto por razones de lentitud): 

En la mayoría de los casos, obtenemos TLE mientras usamos la clase de escáner. Utiliza los métodos integrados nextInt(), nextLong(), nextDouble para leer el objeto deseado después de iniciar el objeto del escáner con el flujo de entrada (por ejemplo, System.in). El siguiente programa muchas veces obtiene un veredicto de límite de tiempo excedido y, por lo tanto, no es de mucha utilidad.

Java

// Working program using Scanner
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Scanner;
public class Main {
    public static void main(String[] args)
    {
        Scanner s = new Scanner(System.in);
        int n = s.nextInt();
        int k = s.nextInt();
        int count = 0;
        while (n-- > 0) {
            int x = s.nextInt();
            if (x % k == 0)
                count++;
        }
        System.out.println(count);
    }
}

 

2. BufferedReader (rápido, pero no recomendado ya que requiere mucho tipeo): 

La clase Java.io.BufferedReader lee texto de un flujo de entrada de caracteres, almacenando en búfer los caracteres para proporcionar una lectura eficiente de caracteres, arrays y líneas. Con este método, tendremos que analizar el valor cada vez para el tipo deseado. Leer varias palabras de una sola línea aumenta su complejidad debido al uso de Stringtokenizer y, por lo tanto, no se recomienda. Estos se aceptan con un tiempo de ejecución de aproximadamente 0,89 s, pero aún así, como puede ver, requiere escribir mucho y, por lo tanto, se recomienda el método 3. 

Java

// Working program using BufferedReader
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
  
public class Main {
    public static void main(String[] args)
        throws IOException
    {
  
        BufferedReader br = new BufferedReader(
            new InputStreamReader(System.in));
  
        StringTokenizer st
            = new StringTokenizer(br.readLine());
        int n = Integer.parseInt(st.nextToken());
        int k = Integer.parseInt(st.nextToken());
        int count = 0;
        while (n-- > 0) {
            int x = Integer.parseInt(br.readLine());
            if (x % k == 0)
                count++;
        }
        System.out.println(count);
    }
}

 

3.Clase FastReader definida por el usuario (que usa bufferedReader y StringTokenizer): 

Este método utiliza la ventaja de tiempo de BufferedReader y StringTokenizer y la ventaja de los métodos definidos por el usuario para escribir menos y, por lo tanto, una entrada más rápida. Estos se aceptan con un tiempo de 1,23 s y este método es muy recomendable ya que es fácil de recordar y lo suficientemente rápido para satisfacer las necesidades de la mayoría de las preguntas en la codificación competitiva.

Java

// Working program with FastReader
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Scanner;
import java.util.StringTokenizer;
  
public class Main {
    static class FastReader {
        BufferedReader br;
        StringTokenizer st;
  
        public FastReader()
        {
            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 {
                if(st.hasMoreTokens()){
                    str = st.nextToken("\n");
                }
                else{
                    str = br.readLine();
                }
            }
            catch (IOException e) {
                e.printStackTrace();
            }
            return str;
        }
    }
  
    public static void main(String[] args)
    {
        FastReader s = new FastReader();
        int n = s.nextInt();
        int k = s.nextInt();
        int count = 0;
        while (n-- > 0) {
            int x = s.nextInt();
            if (x % k == 0)
                count++;
        }
        System.out.println(count);
    }
}

 

4. Uso de la clase de lector

Existe otra forma rápida de resolver el problema, diría que la forma más rápida, pero no se recomienda ya que requiere métodos muy engorrosos en su implementación. Utiliza inputDataStream para leer el flujo de datos y utiliza el método read() y los métodos nextInt() para tomar entradas. Esta es, con mucho, la forma más rápida de recibir información, pero es difícil de recordar y engorrosa en su enfoque. A continuación se muestra el programa de ejemplo que utiliza este método. Estos se aceptan con un tiempo sorprendente de solo 0,28 s. Aunque esto es ultrarrápido, claramente no es un método fácil de recordar.

Java

// Working program using Reader Class
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Scanner;
import java.util.StringTokenizer;
  
public class Main {
    static class Reader {
        final private int BUFFER_SIZE = 1 << 16;
        private DataInputStream din;
        private byte[] buffer;
        private int bufferPointer, bytesRead;
  
        public Reader()
        {
            din = new DataInputStream(System.in);
            buffer = new byte[BUFFER_SIZE];
            bufferPointer = bytesRead = 0;
        }
  
        public Reader(String file_name) throws IOException
        {
            din = new DataInputStream(
                new FileInputStream(file_name));
            buffer = new byte[BUFFER_SIZE];
            bufferPointer = bytesRead = 0;
        }
  
        public String readLine() throws IOException
        {
            byte[] buf = new byte[64]; // line length
            int cnt = 0, c;
            while ((c = read()) != -1) {
                if (c == '\n') {
                    if (cnt != 0) {
                        break;
                    }
                    else {
                        continue;
                    }
                }
                buf[cnt++] = (byte)c;
            }
            return new String(buf, 0, cnt);
        }
  
        public int nextInt() throws IOException
        {
            int ret = 0;
            byte c = read();
            while (c <= ' ') {
                c = read();
            }
            boolean neg = (c == '-');
            if (neg)
                c = read();
            do {
                ret = ret * 10 + c - '0';
            } while ((c = read()) >= '0' && c <= '9');
  
            if (neg)
                return -ret;
            return ret;
        }
  
        public long nextLong() throws IOException
        {
            long ret = 0;
            byte c = read();
            while (c <= ' ')
                c = read();
            boolean neg = (c == '-');
            if (neg)
                c = read();
            do {
                ret = ret * 10 + c - '0';
            } while ((c = read()) >= '0' && c <= '9');
            if (neg)
                return -ret;
            return ret;
        }
  
        public double nextDouble() throws IOException
        {
            double ret = 0, div = 1;
            byte c = read();
            while (c <= ' ')
                c = read();
            boolean neg = (c == '-');
            if (neg)
                c = read();
  
            do {
                ret = ret * 10 + c - '0';
            } while ((c = read()) >= '0' && c <= '9');
  
            if (c == '.') {
                while ((c = read()) >= '0' && c <= '9') {
                    ret += (c - '0') / (div *= 10);
                }
            }
  
            if (neg)
                return -ret;
            return ret;
        }
  
        private void fillBuffer() throws IOException
        {
            bytesRead = din.read(buffer, bufferPointer = 0,
                                 BUFFER_SIZE);
            if (bytesRead == -1)
                buffer[0] = -1;
        }
  
        private byte read() throws IOException
        {
            if (bufferPointer == bytesRead)
                fillBuffer();
            return buffer[bufferPointer++];
        }
  
        public void close() throws IOException
        {
            if (din == null)
                return;
            din.close();
        }
    }
  
    public static void main(String[] args)
        throws IOException
    {
        Reader s = new Reader();
        int n = s.nextInt();
        int k = s.nextInt();
        int count = 0;
        while (n-- > 0) {
            int x = s.nextInt();
            if (x % k == 0)
                count++;
        }
        System.out.println(count);
    }
}

 

Lectura sugerida: 

Prueba de entrada enorme diseñada para verificar el manejo rápido de entrada de su idioma. Los horarios de todos los programas se indican en SPOJ. 
 

Este artículo es una contribución de Rishabh Mahrsee . Si le gusta GeeksforGeeks y le gustaría contribuir, también puede escribir un artículo y enviarlo por correo a review-team@geeksforgeeks.org. Vea su artículo que aparece en la página principal de GeeksforGeeks y ayude a otros Geeks.

Escriba comentarios si encuentra algo incorrecto o si desea compartir más información sobre el tema tratado anteriormente.

Cursos relacionados

Fundamentos de programación Java: curso a su propio ritmo

Desarrolle su base Java sólida con nuestra base de programación Java: curso a su propio ritmo . Este curso a su propio ritmo le brinda el comienzo correcto con los conceptos básicos de JAVA, variables y tipos de datos, operadores, strings y mucho más. Este curso está diseñado para principiantes absolutos que buscan mejorar sus habilidades al siguiente nivel. ¡Empieza a aprender ahora!

Publicación traducida automáticamente

Artículo escrito por GeeksforGeeks-1 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *