patternjavaMinor
Split function while reading multiple lines
Viewed 0 times
readingwhilefunctionsplitmultiplelines
Problem
The input begins with the number \$t\$ of test cases in a single line
(\$t \le 10\$). In each of the next t lines there are two or more
numbers \$m\$ and \$n\$ (\$1 \le m \le n \le 1000000000\$, \$n-m \le 100000\$) separated by a space.
Print each number in a separate line which can be used further for
summation.
Input
Output
This is the code that I've written that is giving me output:
```
import java.util.Scanner;
import java.util.StringTokenizer;
public class Generation {
public static void main(String[] str) {
Scanner keyboard = new Scanner(System.in);
int inputSize;
do {
System.out.println("Enter the value of T Size");
inputSize = keyboard.nextInt();
keyboard.nextLine();
if (inputSize 10) {
System.out.println("Not a Valid Input Size");
}
} while (inputSize 10);
String[] inputValue = new String[inputSize];
int tokenCount = 0;
for (int i = 0; i < inputSize; i++) {
System.out.println("Enter the inputs");
inputValue[i] = keyboard.nextLine();
StringTokenizer strToken = new StringTokenizer(inputValue[i], " ");
tokenCount += strToken.countTokens();
}
keyboard.close();
//suppose this is 2nd part
int[] splitedString = new int[tokenCount];
int tempTokenCount = 0;
for (int i = 0; i < inputSize; i++) {
String[] tempSplitArray = inputValue[i].split(" ");
for (int j = 0; j < tempSplitArray.length; j++) {
splitedString[tempTokenCount] = Integer
.parseInt(tempSplitArray[j]);
tempTokenCount++;
}
}
/*for (String s : inputValue) {
System.out.println(s);
}*/
for (Integer s : splitedString) {
System.out.println(s
(\$t \le 10\$). In each of the next t lines there are two or more
numbers \$m\$ and \$n\$ (\$1 \le m \le n \le 1000000000\$, \$n-m \le 100000\$) separated by a space.
Print each number in a separate line which can be used further for
summation.
Input
2
50 100
100 50 105Output
50
100
100
50
105This is the code that I've written that is giving me output:
```
import java.util.Scanner;
import java.util.StringTokenizer;
public class Generation {
public static void main(String[] str) {
Scanner keyboard = new Scanner(System.in);
int inputSize;
do {
System.out.println("Enter the value of T Size");
inputSize = keyboard.nextInt();
keyboard.nextLine();
if (inputSize 10) {
System.out.println("Not a Valid Input Size");
}
} while (inputSize 10);
String[] inputValue = new String[inputSize];
int tokenCount = 0;
for (int i = 0; i < inputSize; i++) {
System.out.println("Enter the inputs");
inputValue[i] = keyboard.nextLine();
StringTokenizer strToken = new StringTokenizer(inputValue[i], " ");
tokenCount += strToken.countTokens();
}
keyboard.close();
//suppose this is 2nd part
int[] splitedString = new int[tokenCount];
int tempTokenCount = 0;
for (int i = 0; i < inputSize; i++) {
String[] tempSplitArray = inputValue[i].split(" ");
for (int j = 0; j < tempSplitArray.length; j++) {
splitedString[tempTokenCount] = Integer
.parseInt(tempSplitArray[j]);
tempTokenCount++;
}
}
/*for (String s : inputValue) {
System.out.println(s);
}*/
for (Integer s : splitedString) {
System.out.println(s
Solution
try-with-resourcesIf you're on Java 7, you should use
try-with-resource on your Scanner:try (Scanner scanner = new Scanner(System.in)) {
// your code here
}This takes care of closing your
Scanner at the end, so you do not have do perform an explicit close().First input
I am not too sure why are you ensuring
inputSize cannot be less than 2, since the problem statement only mentioned
-
Read in a line for x times
Stream.generate(scanner::nextLine)
This creates a new stream where each element is read from the scanner, i.e. System.in, i.e. the user input. This is accessed via a method reference.
-
On each line, split by a ' ' character
stream.flatMap(Pattern.compile(" ")::splitAsStream)
Pattern.splitAsStream(CharSequence) is a convenient way of tokenizing a line as a stream, which in turn allows us to perform a flatMap() by replacing each element of the source stream with the contents of the resulting stream.
-
Convert each token as an integer within a certain range
stream.map(Generation::convert)
The sample implementation shown below for convert(String) does not perform any validation. Actually, as a result of the flatMap() operation in the previous step, it will be quite tricky to make sure that \$1 \le m \le n \le 1000000000\$, so I'll leave this as an exercise to the reader... (hint: map each String input as a List to facilitate the validation first).
-
Collect all results into a Collection for further usage
stream.filter(Objects::nonNull).collect(Collectors.toList())
Since convert(String) may give us null values for invalid integers, we need to exclude them first. Collecting as toList() is just for illustration. If you want to sum the results together immediately, for example, you can change that to .mapToInt(Integer::intValue).sum()`.public class Generation { // you probably need a better name too
public static void main(String[] args) {
try (Scanner scanner = new Scanner(System.in)) {
List result = Stream.generate(scanner::nextLine)
.limit(getCount(scanner))
.flatMap(Pattern.compile(" ")::splitAsStream)
.map(Generation::convert)
.filter(Objects::nonNull)
.collect(Collectors.toList());
result.forEach(System.out::println);
}
}
private static int getCount(Scanner scanner) {
// see implementation above
}
private static Integer convert(String value) {
try {
return Integer.valueOf(value);
} catch (NumberFormatException e) {
return null;
}
}
}Code Snippets
try (Scanner scanner = new Scanner(System.in)) {
// your code here
}private static int getCount(Scanner scanner) {
System.out.println("Enter the value of T Size [0, 10]:");
int value = scanner.nextInt();
while (value < 0 || value > 10) {
System.out.println("Value is not within [0, 10], try again.");
value = scanner.nextInt();
}
scanner.nextLine(); // gotcha
return value;
}stream.limit(getCount(scanner))Stream.generate(scanner::nextLine)stream.flatMap(Pattern.compile(" ")::splitAsStream)Context
StackExchange Code Review Q#90794, answer score: 6
Revisions (0)
No revisions yet.