How to parse a text file into two parts using Scanner - java

Input (white space delimited):
1 1 2 3
2 1 7
3 3 7
4 1 5
5 3 6
I would like to process these input as like:
For each line in the text file :: (first_element, e.g. 1) into an int variable (say, m) and the following (next_elements, e.g. 1 2 3) into an ArrayList (say, N)
I tried the below:
Scanner file_scanner = new Scanner(filename);
while (file_scanner.hasNextLine()) {
String[] line = file_scanner.nextLine().split("\\s+");
String str1 = line[0];
String str2 = line[1];
m = Integer.parseInt(str1);
Scanner line_scanner = new Scanner(str2);
while(line_scanner.hasNext()) {
int n = line_scanner.nextInt();
N.add(n);
}
}
But I am not able to parse the inputs as I intended to. Any kind suggestions on how to handle two parts of an input line using Scanner? or, even how to check the end of the current line (EOL) as well as how to parse the first element more easily?

try this String[] line = file_scanner.nextLine().split("\\s+",2); in your code. It will split each line into 2 tokens only.
EDIT: line[1] will contain the rest of the numbers, you do not need to parse it again.

Sorry it might not be the most efficient since it's 4:39 am:
Scanner s = new Scanner(file);
int m = 0;
List<Integer> list = null;
while(s.hasNextLine())
{
Scanner s2 = new Scanner(s.nextLine());
int count = 0;
list = new ArrayList<Integer>();
while (s2.hasNextInt())
{
if(count == 0)
{
m = s2.nextInt();
}
else
{
list.add(s2.nextInt());
}
count++;
}
System.out.println(m + " " + list);
}

Related

Split long sting in new lines and check each line first word in java

I have a string that I split based on delimiter on new lines. I'm wondering now how to check the first word index[0] what word is but can't find a way to actually go trough the elements and check.
May be my approach is totally wrong.
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String line = scanner.nextLine();
String[] stringArr = line.split(">>");
int ask = 0;
for (int i = 0; i < stringArr.length; i++) {
if (stringArr[0].equals("radio")) {
ask = 10;
} else if (Objects.equals(stringArr[0], "tv")) {
ask = 15;
} else {
System.out.println("Invalid media.");
}
}
System.out.println(ask);
}
Then when I input radio 3 7210>>tv 4 2345>>radio 9 31000>>
The output should be:
10
15
10
Instead - got nothing. Empty line and the program ends.
Is something like this what you want:
Scanner scanner = new Scanner(System.in);
String line = scanner.nextLine();
String[] stringArr = line.split(">>");
for (int i = 0; i < stringArr.length; i++) {
int ask = 0;
String[] words = stringArr[i].split(" ");
if (words[0].equals("radio")) {
ask = 10;
System.out.println(ask);
} else if (words[0].equals("tv")) {
ask = 15;
System.out.println(ask);
} else {
System.out.println("Invalid media.");
}
}
Input:
radio 3 7210>>tv 4 2345>>radio 9 31000>>
Output:
10
15
10
First of all, I defined the scanner, not sure if you did that but pretty sure you did.
The elements of stringArr will include the random numbers between each ">>". That means, in each element, we should create a new list split by " " to isolate the "radio" and "tv" as the first element.
Additionally, I just rewrote the else-if statement that checks if the first word of the phrases separated by ">>" is "tv" by using the .equals() method as your original if statement did.
Finally, since you are printing out a number EACH time the code encounters a ">>", we should print out ask inside of the for loop.
EDIT:
Moved the System.out.println(ask) inside of the if and else-if statements so it will only run with valid media.
Other than that your code worked perfectly :> , let me know if you have any further questions or clarifications!

How can i only read Strings or Integers when i read .txt file with Scanner Class in Java

Hey guys this is my first question so if i have any mistakes or faults , i am sorry about that.
So i am working on one thing which i'm currently keep failing of and that is ,as it says in the title, reading only strings and integers from .txt file. Here is my code:
File file = new File("C:\\Users\\Enes\\Desktop\\test.txt");
Scanner scn = new Scanner(file);
String[] s = new String[10];
int i = 0;
int[] fruits = new int[10];
while (scn.hasNextInt()) {
fruits[i++] = scn.nextInt();
}while (scn.hasNext()) {
s[i++] = scn.next();
}
for (int elm : fruits) {
System.out.print(elm + "\t");
System.out.println("\n");
}
for (String ele : s) {
System.out.print(ele + "\t");
}
And here is what writes on .txt file
Apple 5
Pear 3
Output is like:
0 0 0 0 0 0 0 0 0 0
Apple 5 Pear 3 null null null null null null
So i want to get Apple and Pear, the strings in different array and 5 and 3 which is integers in different array. How can i do this? Any help would be so appreciated. Thanks all!
First, I'd rename your variables to something useful:
String[] names = new String[10];
int[] counts = new int[10];
Right now, you're trying to grab all 10 numbers and then all 10 names. But that isn't how your data is laid out.
I would use the scanner to grab the line, and split it from there:
Scanner sc = new Scanner(new File(file));
int index = 0;
while(sc.hasNextLine()) {
String line = sc.nextLine();
String[] tokens = line.split(" ");
names[index] = tokens[0];
counts[index] = Integer.parseInt(tokens[1]);
index++;
}
For output, we iterate both loops at the same time:
for(int i = 0; i < 10; i++) {
System.out.println(names[i] + "\t" + counts[i]);
}
This is an adaption of corsiKa's answer (which is-in-of-itself, correct +1), but which demonstrates using a second Scanner to parse the line ...
int index = 0;
while (sc.hasNextLine()) {
String line = sc.nextLine();
Scanner lineScanner = new Scanner(line);
names[index] = lineScanner.next();
counts[index] = lineScanner.nextInt();
index++;
}
because people seem to forget that Scanner can parse String values

How to replace multiple occurences of a character in a java string using replace and charAt methods

This is my second question here and still a beginner so please bear with me.
I have this code of a very basic hangman type game.I have changed the characters to "-",I am able to get the indices of the input but I am not able to convert back the "-" to the characters entered.
Its an incomplete code.
String input;
String encrypt = line.replaceAll("[^ ]","-");
System.out.println(encrypt);
for (int j=0;j<10;j++){ //Asks 10 times for user input
input = inpscanner.nextLine();
int check = line.indexOf(input);
while (check>=0){
//System.out.println(check);
System.out.println(encrypt.replaceAll("-",input).charAt(check));
check = line.indexOf(input,check+1);
}
Here is how it looks like:
You have 10 chances to guess the movie
------
o
o
o
L
L
u //no repeat because u isn't in the movie.While 'o' is 2 times.
I would like to have it like loo---(looper).
How can I do like this "[^ ]","-" in case of a variable?
This might help.
public static void main(String[] args) {
String line = "xyzwrdxyrs";
String input;
String encrypt = line.replaceAll("[^ ]","-");
System.out.println(encrypt);
System.out.println(line);
Scanner scanner = new Scanner(System.in);
for (int j=0;j<10;j++) { //Asks 10 times for user input
input = scanner.nextLine();
//int check = line.indexOf(input);
int pos = -1;
int startIndex = 0;
//loop until you all positions of 'input' in 'line'
while ((pos = line.indexOf(input,startIndex)) != -1) {
//System.out.println(check);
// you need to construct a new string using substring and replacing character at position
encrypt = encrypt.substring(0, pos) + input + encrypt.substring(pos + 1);
//check = line.indexOf(input, check + 1);
startIndex = pos+1;//increment the startIndex,so we will start searching from next character
}
System.out.println(encrypt);
}
}

How to read multiple integers in multiple lines when the number of integers in each line is unknown

EDIT: This is the input:
1st number is m, followed by m numbers. Next entry is n followed by n lines, each with varying and unknown number of elements.
5
1 2 3 4 5
3
1 2 3 4 5 6
1 2 3 4 5
1 2 3 4
How can I read this input in Java using the scanner class? nextInt doesn't seem to take the next line character into account.
One way is to take the whole line as input and get the integers from it but am looking for something faster.
My code works for the following constraints:
1 ≤ M ≤ 10
1 ≤ N ≤ 100
The number of elements in the n lines ranges between 1 and 100
but times out for the following(takes more than 3s):
1 ≤ M ≤ 100
1 ≤ N ≤ 9 x 103
The number of elements in the n lines ranges between 1 and 1000
Here's what am doing:
public static void main(String[] str) {
Scanner in = new Scanner(System.in);
ArrayList<Integer> qualities = new ArrayList<Integer>();
int m = in.nextInt();
in.nextLine();
for(int i=0;i<m;i++)
qualities.add(in.nextInt());
int n = in.nextInt();
in.nextLine();
for(int j=0;j<n;j++) {
HashSet<Integer> qua = new HashSet<Integer>();
String[] strng = in.nextLine().split(" ");
for(String x: strng)
qua.add(Integer.parseInt(x));
solve(qua);
}
System.out.print(count);
}
Just wanted to know if there is a way I can avoid using in.nextLine() while reading the line with multiple integers and just use in.nextInt() instead.
The number of integers in each line varies and is unknown.
How can I read this input in Java using the scanner class?
To detect new line with Scanner, you need to have 2 things.
1)Grasp the first line say L.
2)Feed L into a new Scannerand get your Ints.
Something like:
Scanner scan=new Scanner(new File("input.txt"));
while(scan.hasNext())
{
String s=scan.nextLine();
Scanner inscan=new Scanner(s);
while(inscan.hasNext())
System.out.print(" "+inscan.nextInt());
System.out.println("");
inscan.close();
}
scan.close();
Try this:
String contents =
"3\n" +
"1 2 3 4 5 6\n" +
"1 2 3 4 5\n" +
"1 2 3 4\n";
int[][] result = null;
try (BufferedReader reader = new BufferedReader(new StringReader(contents))) {
int i = 0;
int count = 0;
String line;
while ((line = reader.readLine()) != null)
if (result == null)
result = new int[count = Integer.parseInt(line)][];
else if (i < count)
result[i++] = Stream.of(line.split(" "))
.mapToInt(s -> Integer.parseInt(s))
.toArray();
else
break;
}
for (int[] line : result)
System.out.println(Arrays.toString(line));
// result:
// [1, 2, 3, 4, 5, 6]
// [1, 2, 3, 4, 5]
// [1, 2, 3, 4]
If you are using Scanner you don't need to do anything other than use it. This code works for both a string input and direct input from the system input. As you can see it is a simple use of Scanner, the only change is to decide which way you want to instantiate the scanner, i.e. to select either a String or System.input source.
public static void main(String[] args)
{
System.out.println("\nInput some numbers (end by typing a non number)"); //$NON-NLS-1$
String contents =
"1 2 3 4 5\n" +
"1 3 5 7 9\n" +
"5 4 3 2 1\n" +
"100 33 -146\n";
// scanner form string
Scanner sc = new Scanner(contents);
// scanner from system input
// Scanner sc = new Scanner(System.in);
List<Integer> li = new LinkedList<>();
while (true)
{
try
{
Integer i = sc.nextInt();
li.add(new Integer(i));
}
catch(InputMismatchException e)
{
break;
}
catch(NoSuchElementException e)
{
break;
}
}
Integer sum = 0;
for (Integer i : li)
{
sum += i;
}
StringBuilder sb = new StringBuilder("sum = ").append(sum); //$NON-NLS-1$
System.out.println(sb.toString());
sc.close();
}
running with the Scanner linked to the String or the System input produces the same result
42
No special handling of \n is required due to the whitespace rules employe din java.
EDIT:
The InputMismatchException exception is thrown when the System.input source is used and you enter a non number, like an X. The NoSuchElementException exception is thrown when the source is a String and the input is exhausted.
This is just an example, you woul dhave to handle end of System.input better for production code.

Using Scanner with sequence of Integers

I'm writing a program to take a sequence of integers from console, e.g.
1 5 3 4 5 5 5 4 3 2 5 5 5 3
then compute the number of occurrences and print the following output:
0 - 0
1 - 1
2 - 1
3 - 3
4 - 2
5 - 7
6 - 0
7 - 0
8 - 0
9 - 0
where the second number is the number of occurrences of the first number.
Code:
public static void main (String args[])
{
Scanner chopper = new Scanner(System.in);
System.out.println("Enter a list of number: ");
int[] numCount = new int[10];
int number;
while (chopper.hasNextInt()) {
number = chopper.nextInt();
numCount[number]++;
}
for (int i = 0; i < 10; i++) {
System.out.println(i + " - " + numCount[i]);
}
}
But after inputing the sequence, we must type a non-integer character and press "Enter" to terminate the Scanner and execute the "for" loop. Is there any way that we don't have to type a non-integer character to terminate the Scanner?
You could get out by pressing Enter followed by Control-D.
If you don't want to do that, then there's no other way with a Scanner.
You will have to read the input by some other way, for example with a BufferedReader:
String line = new BufferedReader(new InputStreamReader(System.in)).readLine();
Scanner chopper = new Scanner(line);
Even better (inspired by #user3512478's approach), with two Scanners, without BufferedReader:
Scanner chopper = new Scanner(new Scanner(System.in).nextLine());
Best way IMO:
String str;
Scanner readIn = new Scanner(System.in);
str = readIn.nextLine();
String[] nums = str.split(" ");
int[] finalArray = new int[nums.length];
for(int i = 0; i < nums.length; i++) {
finalArray[i] = Integer.parseInt(nums[i]);
return finalArray;
Hope this helps!
Best way: Not just for this pattern, for any kind of sequence input recognition, modify delimiter of Scanner object to get required sequence recognized.
Here, in this case, change chopper delimiter to whitespace character (Spaces). i.e "\\s". You can also use "\\s*" for specifying zero or more occurrence of whitespace characters
This makes Scanner to check for spaces rather than waiting for Enter key stroke.
public static void main (String args[])
{
Scanner chopper = new Scanner(System.in).useDelimiter("\\s"); \\ Delimiter changed to whitespace.
System.out.println("Enter a list of number: ");
int[] numCount = new int[10];
int number;
while (chopper.hasNextInt()) {
number = chopper.nextInt();
numCount[number]++;
}
for (int i = 0; i < 10; i++) {
System.out.println(i + " - " + numCount[i]);
}
}
Try using a for loop.
for (int i:1; i<10;i++) {
chopper.hasNextInt()
number = chopper.nextInt();
numCount[number]++;
}
From Oracle Doc it says:
A scanning operation may block waiting for input.
Both hasNext and next methods may block waiting for further input

Categories

Resources