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

Автор __goku__, история, 4 года назад, По-английски

Many coders who like coding in Java for competitive coding have faced a “TLE” even though their logic and complexity are well within the bounds. The problem in those cases lies in our way of I/O. Using Scanner and System.out.println() in a code is quite convenient but often make our program slow. I am sharing my article in which I have shared my template. I urge fellow coders to check this out and please do notify me if anything can be improved. Thank You!

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

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

Your code is wayyyyyy too long. You can compress your entire input section to this and then just used FastScanner instead of Scanner:

        static class FastScanner {
		BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st=new StringTokenizer("");
		String next() {
			while (!st.hasMoreTokens())
				try { 
                                        st=new StringTokenizer(br.readLine());				               
                                } catch (IOException e) {}
			return st.nextToken();
		}
		
		int nextInt() {
			return Integer.parseInt(next());
		}
		long nextLong() {
			return Long.parseLong(next());
		}
	}

I regularly just type this instead of going to find a template if I get on my computer a minute or two before a contest.

Also, your output is similarly convoluted. You can just add PrintWriter out=new PrintWriter(System.out); to the top of your code, and then replace all System.out* calls with out.* calls, and then add out.close(); to the end of your main method. It's quite easy and doesn't require a template at all.

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

    When taking an input as a String using this code, it sometimes outputs only certain part of it.

    For eg. If we have to take an input {a, b, c} as a string it only take {a, as the input.

    I got this issue when i was solving https://codeforces.com/problemset/problem/443/A

    Is there a solution to fix it?

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

      If you want to read the whole line, you can call br.readLine() instead of just getting the next token.

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

    I think his input method is fine (after all, templates aren't supposed to be the shortest). The method of reading in input using DataInputStream is faster than the BufferedReader + StringTokenizer combo for ints. They are about the same speed for strings. Nevertheless, this difference is all it takes for a TLE submission to become AC in judges with tight limits (CSES for example). However, BufferedReader + StringTokenizer is a lot less error-prone and has a lot less potential problems than DataInputStream. For that reason, I still prefer to use it for interactive problems.

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

the best way to use java in CP is to not use it

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

As SecondThread pointed out, your code is very convoluted. You don't need extra methods for inputting and using a BufferedWriter as your output is probably one of the worst things you could do to yourself.

First off, if you want to use BufferedWriter for outputting, you should probably just use new PrintWriter(System.out);. This is the equivalent of outputting to stdout with a BufferedWriter but it's much more convenient.

Also, GFG's input template is fine but there are some issues. the readLine() method will only work for lines that have length less than or equal to 64. A fix is to either use a StringBuilder with an initial capcity or change the method to readLine(int lineLength) where lineLength specifies the length of the line.

Finally, the fastest output method I've been able to find so far is to use a BufferedOutputStream (or just a normal OutputStream) with a StringBuilder. The basic idea is to print everything to the StringBuilder, and then flush the StringBuilder once it hits a certain size. This method is much faster than BufferedWriter for printing a large number of short strings (ints for example).

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

    Yes I noticed it after a while. Thanks but can you please elaborate on what is the problem with BufferedWriter?

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

      I don't know about you but I'd rather type pw.println(/*you can put practically anything here*/); Than something like bw.write(/*has to be a string so much more inconvenient for stuff like ints*/);