-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathOpenScan.java
More file actions
340 lines (317 loc) · 11.2 KB
/
OpenScan.java
File metadata and controls
340 lines (317 loc) · 11.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.StringTokenizer;
/* v1.0
* Assuming that sc is your OpenScan object,
* sc.next() reads the next token from the input.
* sc.nextInt() reads the next token as an integer.
* sc.nextDouble() reads the next token as a double.
* sc.nextLine() reads the next line of text.
* sc.nextChar() reads the first character of the next token.
* sc.nextBoolean() reads the next token as a boolean.
* sc.nextShort() reads the next token as a short.
* sc.nextByte() reads the next token as a byte.
* sc.nextLong() reads the next token as a long.
* sc.nextFloat() reads the next token as a float.
* sc.nextStringList() reads all remaining tokens from the current line as Strings.
* sc.nextIntArray(int count) reads multiple integers from the current line.
* sc.nextLongArray(int count) reads multiple longs from the current line.
* sc.nextDoubleArray(int count) reads multiple doubles from the current line.
* sc.readAllInts() reads all integers from the input until the end of input.
* sc.readAllDoubles() reads all doubles from the input until the end of input.
* sc.readAllLongs() reads all longs from the input until the end of input.
* sc.readAllStrings() reads all strings from the input until the end of input.
* sc.skipLines(int linesToSkip) skips a specified number of lines from the input.
* sc.hasNext() checks if there is another token available.
* sc.close() closes the underlying BufferedReader.
*/
public class OpenScan implements AutoCloseable {
private BufferedReader reader;
private StringTokenizer tokenizer;
private String line;
/**
* Constructs a new OpenScan object that reads from System.in.
*/
public OpenScan() {
reader = new BufferedReader(new InputStreamReader(System.in));
}
/**
* Reads the next token from the input.
*
* @return The next token as a String.
* @throws NoSuchElementException if there are no more tokens.
* @throws RuntimeException if an I/O error occurs.
*/
public String next() {
while (tokenizer == null || !tokenizer.hasMoreTokens()) {
try {
line = reader.readLine();
if (line == null) {
throw new NoSuchElementException("End of input reached");
}
tokenizer = new StringTokenizer(line);
} catch (IOException e) {
throw new RuntimeException("Error reading from input", e);
}
}
return tokenizer.nextToken();
}
/**
* Reads the next line of text from the input.
*
* @return The line read as a String, or null if the end of the stream is reached.
* @throws RuntimeException if an I/O error occurs.
*/
public String nextLine() {
try {
tokenizer = null; // clear tokenizer for next line
return reader.readLine();
} catch (IOException e) {
throw new RuntimeException("Error reading line from input", e);
}
}
/**
* Reads the next token as an integer.
*
* @return The integer value read.
* @throws NoSuchElementException if there are no more tokens.
* @throws NumberFormatException if the next token is not a valid integer.
* @throws RuntimeException if an I/O error occurs.
*/
public int nextInt() {
return Integer.parseInt(next());
}
/**
* Reads the next token as a long.
*
* @return The long value read.
* @throws NoSuchElementException if there are no more tokens.
* @throws NumberFormatException if the next token is not a valid long.
* @throws RuntimeException if an I/O error occurs.
*/
public long nextLong() {
return Long.parseLong(next());
}
/**
* Reads the next token as a double.
*
* @return The double value read.
* @throws NoSuchElementException if there are no more tokens.
* @throws NumberFormatException if the next token is not a valid double.
* @throws RuntimeException if an I/O error occurs.
*/
public double nextDouble() {
return Double.parseDouble(next());
}
/**
* Reads the next token as a float.
*
* @return The float value read.
* @throws NoSuchElementException if there are no more tokens.
* @throws NumberFormatException if the next token is not a valid float.
* @throws RuntimeException if an I/O error occurs.
*/
public float nextFloat() {
return Float.parseFloat(next());
}
/**
* Reads the next token as a boolean.
*
* @return The boolean value read.
* @throws NoSuchElementException if there are no more tokens.
* @throws RuntimeException if an I/O error occurs.
*/
public boolean nextBoolean() {
return Boolean.parseBoolean(next());
}
/**
* Reads the first character of the next token.
*
* @return The first character read.
* @throws NoSuchElementException if there are no more tokens.
* @throws RuntimeException if the next token is an empty string.
*/
public char nextChar() {
String token = next();
if (token.isEmpty()) {
throw new RuntimeException("Empty token encountered while expecting a character");
}
return token.charAt(0);
}
/**
* Checks if there is another token available.
*
* @return true if another token is available, false otherwise.
*/
public boolean hasNext() {
if (tokenizer != null && tokenizer.hasMoreTokens()) {
return true;
}
try {
line = reader.readLine();
if (line == null) {
return false;
}
tokenizer = new StringTokenizer(line);
return tokenizer.hasMoreTokens();
} catch (IOException e) {
throw new RuntimeException("Error checking for next token", e);
}
}
/**
* Reads the next token as a short.
* @return The short value read.
* @throws NoSuchElementException if there are no more tokens.
* @throws NumberFormatException if the next token is not a valid short.
* @throws RuntimeException if an I/O error occurs.
*/
public short nextShort() {
return Short.parseShort(next());
}
/**
* Reads the next token as a byte.
* @return The byte value read.
* @throws NoSuchElementException if there are no more tokens.
* @throws NumberFormatException if the next token is not a valid byte.
* @throws RuntimeException if an I/O error occurs.
*/
public byte nextByte() {
return Byte.parseByte(next());
}
/**
* Reads multiple integers from the current line.
* @param count The number of integers to read.
* @return An array of integers.
* @throws NoSuchElementException if there are not enough tokens on the current line.
* @throws NumberFormatException if any of the tokens are not valid integers.
*/
public int[] nextIntArray(int count) {
int[] array = new int[count];
for (int i = 0; i < count; i++) {
array[i] = nextInt();
}
return array;
}
/**
* Reads multiple longs from the current line.
* @param count The number of longs to read.
* @return An array of longs.
* @throws NoSuchElementException if there are not enough tokens on the current line.
* @throws NumberFormatException if any of the tokens are not valid longs.
*/
public long[] nextLongArray(int count) {
long[] array = new long[count];
for (int i = 0; i < count; i++) {
array[i] = nextLong();
}
return array;
}
/**
* Reads multiple doubles from the current line.
* @param count The number of doubles to read.
* @return An array of doubles.
* @throws NoSuchElementException if there are not enough tokens on the current line.
* @throws NumberFormatException if any of the tokens are not valid doubles.
*/
public double[] nextDoubleArray(int count) {
double[] array = new double[count];
for (int i = 0; i < count; i++) {
array[i] = nextDouble();
}
return array;
}
/**
* Reads all remaining tokens from the current line as Strings.
* @return A List of String tokens.
*/
public List<String> nextStringList() {
List<String> list = new ArrayList<>();
while (tokenizer != null && tokenizer.hasMoreTokens()) {
list.add(tokenizer.nextToken());
}
return list;
}
/**
* Skips a specified number of lines from the input.
* @param linesToSkip The number of lines to skip.
* @throws RuntimeException if an I/O error occurs.
*/
public void skipLines(int linesToSkip) {
try {
for (int i = 0; i < linesToSkip; i++) {
if (reader.readLine() == null) {
// End of input reached before skipping all lines
return;
}
}
} catch (IOException e) {
throw new RuntimeException("Error skipping lines in input", e);
}
}
/**
* Reads all integers from the input until the end of input.
* @return A list containing all integers read.
* @throws NumberFormatException if any of the tokens are not valid integers.
*/
public List<Integer> readAllInts() {
List<Integer> numbers = new ArrayList<>();
while (hasNext()) {
numbers.add(nextInt());
}
return numbers;
}
/**
* Reads all doubles from the input until the end of input.
* @return A list containing all doubles read.
* @throws NumberFormatException if any of the tokens are not valid doubles.
*/
public List<Double> readAllDoubles() {
List<Double> numbers = new ArrayList<>();
while (hasNext()) {
numbers.add(nextDouble());
}
return numbers;
}
/**
* Reads all longs from the input until the end of input.
* @return A list containing all longs read.
* @throws NumberFormatException if any of the tokens are not valid longs.
*/
public List<Long> readAllLongs() {
List<Long> numbers = new ArrayList<>();
while (hasNext()) {
numbers.add(nextLong());
}
return numbers;
}
/**
* Reads all strings from the input until the end of input.
* @return A list containing all strings read.
*/
public List<String> readAllStrings() {
List<String> strings = new ArrayList<>();
while (hasNext()) {
strings.add(next());
}
return strings;
}
/**
* Closes the underlying BufferedReader.
* This should be called when the OpenScan object is no longer needed,
* preferably using a try-with-resources statement.
*/
@Override
public void close() {
try {
if (reader != null) {
reader.close();
}
} catch (IOException e) {
System.err.println("Warning: Error closing input reader: " + e.getMessage());
}
}
}