__goku__'s blog

By __goku__, history, 4 years ago, In English

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!

  • Vote: I like it
  • -12
  • Vote: I do not like it

| Write comment?
»
4 years ago, # |
  Vote: I like it 0 Vote: I do not like it

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 years ago, # ^ |
      Vote: I like it 0 Vote: I do not like it

    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 years ago, # ^ |
        Vote: I like it 0 Vote: I do not like it

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

  • »
    »
    4 years ago, # ^ |
      Vote: I like it 0 Vote: I do not like it

    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 years ago, # |
  Vote: I like it +13 Vote: I do not like it

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

»
4 years ago, # |
  Vote: I like it 0 Vote: I do not like it

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 years ago, # ^ |
      Vote: I like it 0 Vote: I do not like it

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

    • »
      »
      »
      4 years ago, # ^ |
        Vote: I like it 0 Vote: I do not like it

      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*/);