I have used Scanner(System.in) for a long time, but I am now transitioning to using BufferedReader and StringTokenizer because I heard it runs faster. I am trying to read an input (shown below) using StringTokenizer. I have looked at some posts but I don't see any that solve this particular problem.
5
2 3 2 2 3
This is my code:
import java.util.*;
import java.io.*;
public class FindDistinct {
public static void main(String[] args) throws IOException {
BufferedReader r = new BufferedReader(new InputStreamReader(System.in));
PrintWriter pw = new PrintWriter(System.out);
StringTokenizer st = new StringTokenizer(r.readLine());
int n = Integer.parseInt(st.nextToken());
HashSet<Integer> set = new HashSet<Integer>();
for (int i = 0; i < n; i++) {
set.add(Integer.parseInt(st.nextToken()));
}
pw.println(set.size());
pw.close();
r.close();
}
}
The error I am getting is:
Exception in thread "main" java.util.NoSuchElementException
at java.base/java.util.StringTokenizer.nextToken(StringTokenizer.java:348)
at FindDistinct.main(FindDistinct.java:16)
I think the error is happening because I am reading multiple lines of input. How do I fix this? By the way, this is for competitive programming so I am looking for solutions that would run quickly. Thanks in advance!
From the Javadoc for StringTokenizer
:
- {@code StringTokenizer} is a legacy class that is retained for compatibility reasons although its use is discouraged in new code. It is recommended that anyone seeking this functionality use the {@code split} method of {@code String} or the java.util.regex package instead.
But your problem is that you only read one line from your buffered reader, so your tokeniser only has one token, but then you try to read the next n
tokens from it.
You need to read another line and create another StringTokenizer.
I doubt that any performance difference between this approach and Scanner
would be important. In competitive programming questions finding an efficient algorithm is the key.