Turning a string into multiple arrays? - java

I'm a student who is learning java (just started this year. I just graduated so I can't ask my high school teacher for help, either), and I need some help on how to turn a string into multiple arrays(?).
However, after this I get stuck (because I can't find a way to break down the string for my purposes).
The file is read like this
Input: The first line will be the number of cases. For each case the
first line will be Susan’s work schedule, and the second line will be
Jurgen’s work schedule. The work schedules will be the date of the
month (1-30) which they work. The third line will be the size of the
initial TV.
The file in question:
3
2 5 10
2 4 10
60
2 4 10
2 5 10
60
1 2 3 4 7 8 10 12 14 16 18 20 24 26 28 30
1 2 3 6 9 10 17 19 20 21 22 23 25 27 28 29
20
I'm not sure how to go about this. I've tried .split(), but that only seems to work on the first row in the string. Any help/tips you might have would be greatly appreciated!

you may read your input by lines and then apply regex on them to separate numbers from string like:
String numbers = "1 2 3 4 7 8 10 12 14 16 18 20 24 26 28 30";
String[] singleNumbers = numbers.split(" ");
then you will have these numbers separated by space in singleNumbers array

Depending on how you are reading the file, you are probably using something like the following:
BufferedReader in = new BufferedReader(new FileReader("foo.in"));
Then, to read the file line by line:
String theLine = in.readLine();
Now you have the string corresponding to the line (in this case the first line, but you can call readLine() over and over to read them all), but note you do not read the 'whole' file at once to get all the Strings, as I think you are suggesting, rather the reader takes a line at a time.
Therefore, if you want all the lines held in an array, all you need to do is declare the array, and then read each line into it. Something like:
// Declare an array to put the lines into
int numberOfLines = 10;
String[] arrayOfStrings = new String[numberOfLines];
// Read the first line
String aLine = in.readLine();
int i = 0;
// If the line that has been read is null, it's reached the end of the file
// so stop reading
while(aLine != null){
arrayOfStrings[i] = aLine;
i++;
aLine = in.readLine();
}
// arrayOfStrings elements are now each line as a single String!
Of course, you may not know how many lines are in the file to be read in the first case, so declaring the size of the array is difficult. You could then look into a dynamically-scaling data structure such as ArrayList, but that is a separate matter.

Hey I got a great solution for you.
Just make a class to store each student's data like
import java.util.List;
public class Student {
private int noOfCases;
private List<String> workSchedule;
private List<String> initialTV;
//getter setters
}
Then this...
public static void main(String[] args) {
//3 students for reading 9 lines
//Susan, Jurgen and You ;)
Student[] students = new Student[3];
int linesRead = 0;
String aLine = null;
// read each line through aLine
for (Student student : students) {
//use buffered/scanner classes for reading input(each line) in aLine
while (aLine != null) {
++linesRead;
if (linesRead == 1) {
student.setNoOfCases(Integer.valueOf(aLine));
++linesRead;
} else if (linesRead == 2) {
student.setWorkSchedule(Arrays.asList(aLine.split(" ")));
++linesRead;
} else if (linesRead == 3) {
student.setInitialTV(Arrays.asList(aLine.split(" ")));
} else {
linesRead = 0;
}
}
}
}
}
If you need to read more lines/more student's records, just resize the Student Array!!

Given you already have your BufferedReader, you could try something like this to give you a multi dimensional array of your rows and columns:
BufferedReader reader = ...;
List<String[]> lines = new ArrayList<String[]>();
String input;
while((input = reader.readLine()) != null){
if (!input.trim().isEmpty()){
lines.add(input.split(" "));
}
}
String[][] data = lines.toArray(new String[lines.size()][]);

Related

reading a file with mixed data with java

Hello I was wondering if I could get some help. I've been tasked with reading from a file and storing the information into arrays. I have three arrays meant to pick up the data, which for example looks like this:
Smith Jr., Joe
111-22-3333 100 90 80 70 60 88
Jones, Bill
111-11-1111 90 90 87 88 100 66
Brown, Nancy
222-11-1111 100 100 100 100 100 100
My code for reading the data is this so far:
public static void readFile(String[] studentList, String[] idList, int[] scoreList) throws IOException {
String fileName;
System.out.println("Enter file name and location if necessary: ");
fileName = KB.nextLine();
File f1= new File(fileName); // "C:\Users\User\Desktop\final.txt"
Scanner fileIn = new Scanner(f1);
int i = 0 ;
if (f1.length() == 0) {
System.out.println("File is empty");
}
while(fileIn.hasNext() && i < studentList.length){
studentList[i] = fileIn.nextLine();
idList[i] = fileIn.nextLine();
scoreList[i] = fileIn.nextInt();
i++;
}
}
When I go to output the code though, I get this error:
Exception in thread "main" java.util.InputMismatchException
at java.util.Scanner.throwFor(Scanner.java:864)
at java.util.Scanner.next(Scanner.java:1485)
at java.util.Scanner.nextInt(Scanner.java:2117)
at java.util.Scanner.nextInt(Scanner.java:2076)
at managestudent.ManageStudent.readFile(ManageStudent.java:88)
at managestudent.ManageStudent.main(ManageStudent.java:36)
I've tried troubleshooting and what seems to be happening is that my second array stores the entire line and that my integers aren't getting read and stored into my third array.
I tried to set my second array as a long to pick up the numbers like 111-111-111 and differentiate from the integers but that gave me another error which seemed to be that my long array wasn't picking up anything from the second lines at all.
Any suggestions?
Thank you kindly for your time.
You need to make the following changes to your code
studentList[i] = fileIn.nextLine();
String id_score = fileIn.nextLine();
String[] split = id_score.split(" ",2);
idList[i] = split[0];
scoreList[i] = split[1];
.split() will separate the id and score in the second line.
Look at this code:
studentList[i] = fileIn.nextLine();
idList[i] = fileIn.nextLine();
scoreList[i] = fileIn.nextInt();
You are reading line by line.
But 111-22-3333 100 90 80 70 60 88 is a single line (which is read into idList[i]).
You need to change your code in a way, that you read 111-22-3333 100 90 80 70 60 88 as a line, and then split the line into two (or more, that's up to you) segments, that you process further to get ID and scores.
As an alternate to Moritz Petersens answer, for minimal changes to your code, you can use the next() method instead of nextLine() method to get the idList() by changing your while loop as follows;
studentList[i] = fileIn.nextLine();
idList[i] = fileIn.next();
scoreList[i] = fileIn.nextLine();
i++;
This will store the first token (Your ID) into the idList array and the remaining part of that line into the scoreList array. Which I assume you are expecting to happen here.
Refer: https://www.tutorialspoint.com/java/util/scanner_next.htm
Hope this helps!
UPDATE
I just observed that your scoreList array is of type int[].
Based on that, above fix will not work.
You will need to create a temporary string which takes all scores and then split it to put the appropriate integers into the score array.
Also, create a new integer for tracking index of the scoreList array.
Something like;
int scoreIndex = 0;
while(fileIn.hasNext() && i < studentList.length){
studentList[i] = fileIn.nextLine();
idList[i] = fileIn.next();
String scores = fileIn.nextLine();
String[] splitScores = scores.trim.split(" ");
for (String a : splitScores) {
scoreList[scoreIndex] = Integer.parseInt(a);
scoreIndex++;
}
i++;
}
Also, since you are using a primitive array dataType for scoreList array, make sure that the size of the array is number_of_subjects*number_of_students.
In your example, 6*3.

From data to ArrayList

I am importing a file that has the following:
1 2 3 4 5
4 5 6 7 8
10 11 12 13 14 15 16 17
11 13 15 17 19 21 23
4 5 5 6 76 7 7 8 8 8 8 8
23 3 4 3 5 3 53 5 46 46 4 6 5 3 4
I am trying to write a program that will take the first line and add it to ArrayList<Integer>s1 and the second line into ArrayList<Integer>s2. After that, I am calling another method that will use those two (UID.union(s1,s2)). However, I am unable to figure out how to add those numbers into the ArrayList. I wrote the following, but it doesn't work:
ArrayList<Integer> set1 = new ArrayList<Integer>();
TreeSet<Integer> s1 = new TreeSet<Integer>();
Scanner input = new Scanner(new File ("mathsetdata.dat"));
String str []= input.next().split(" ");
Set<String> s11 = new TreeSet<String>(Arrays.asList(str));
for (String k: s11)
{
set1.add(Integer.parseInt(k));
}
Also, I am using a loop that will use the first line as s1, the second as s2, and then call the other class and run it. Then, it will use the third line as s1 and the fourth as s2 and run it again.
Maybe you should use Scanner.nextLine()method. You use next() method will return a single character.
We know that nextInt(), nextLong(), nextFloat() ,next() methods are known as token-reading methods, because they read tokens separated by delimiters.
Although next() and nextLine() both read a string,but nextLine is not token-reading method. The next() method reads a string delimited by delimiters, and nextLine() reads a line ending with a line separator.
Further speak, if the nextLine() mehod is invoked after token-reading methods,then this method reads characters that start from this delimiter and end with the line separator. The line separator is read, but it is not part of the string returned by nextLine().
Suppose a text file named test.txt contains a line
34 567
After the following code is executed,
Scanner input = new Scanner(new File("test.txt"));
int intValue = input.nextInt();
String line = input.nextLine();
intValue contains 34 and line contains the characters ' ', 5, 6, and 7.
So in your code,you can replace with the following code:
Scanner input = new Scanner(new File ("mathsetdata.dat"));
String str []= input.nextLine().split(" ");
List<Integer> list = new ArrayList<Integer>(){};
Scanner input = new Scanner(new File ("mathsetdata.dat"));
while(input.hasNextLine()){
String[] strs= input.nextLine().split(" ");//every single line
for(String s :strs){
list.add(Integer.parseInt(s));
}
is it what you want maybe?
You are not reading file in right way also you are adding redundant code. I have added method to convert a line into List of Integers.
private static List<Integer> convertToList(String line) {
List<Integer> list = new ArrayList<Integer>();
for (String value : line.split(" ")) {
list.add(Integer.parseInt(value));
}
return list;
}
public static void main(String[] args) throws JsonSyntaxException, JsonIOException, FileNotFoundException {
Scanner input = new Scanner(new File("/tmp/mathsetdata.dat"));
while (input.hasNextLine()) {
String line = input.nextLine();
if (line.trim().length() > 0)
System.out.println(convertToList(line));
}
}
I think this is what you are seeking for:
public static List<String> readTextFileToCollection(String fileName) throws IOException{
List<String> allLines = Files.lines(Paths.get(fileName)).collect(Collectors.toList());
ArrayList<String> finalList = allLines.stream()
.map(e->{ return new ArrayList<String>(Arrays.asList(e.split(" ")));})
.reduce(new ArrayList<String>(), (s1,s2) -> UID.union(s1,s2));
return finalList;
}
In order to work this solution; your UID.union(s1,s2) should return the merged arraylist. That means, you should be able to write something like below without compilation errors:
ArrayList<String> mergedList = UID.union(s1,s2);

How to print line until the first letter of the line is different (with scanner or bufferedreader)?

What I am trying to do is make a MATCH. I have an array with a list of numbers like this:
171142229
171142232
171142250
171142254
177073637
but there are a lot more, this is just an example and I have to find each number in all of my files, the content of the files is something like this (can't change this either and there are a lot more also each line begins either with the letter H or the I)
H ZPDV 171 MO ME 8500015847 8500015847 8500015847 8500015847 171142229 20160112 20160112 MXN 0000002978
I 20 6CB 1 10.07 0 16 C2 9019999999171610099277 9019999999171610099277
I 10 61 1 189.93 0 16 C2 9019999999171610099277 9019999999171610099277
H ZPDV 169 MO ME 2000169 2000169 2000169 2000169 169068348 20160112 20160112 MXN 0000012213
I 20 6CB 1 12.00 0 16 C2 7019999999169610019193 7019999999169610019193
I 10 61 1 154.38 0 16 C2 7019999999169610019193 7019999999169610019193
if you notice, the first number 171142229 is found in the the first line which has an H at the beginning.
I want to print al the lines that have an I on the beginning that are below the one with the H and stop until the next H.
The program prints all the lines below, no matter what until the end of the file, then looks the next number in the list of files and do the same and so on.
public static void main(String[] args) throws IOException {
String[] lista = CreaPVF.creaListaPendientes(); //this method creates my list of nubers
String[] rutas = CreaPVF.recorreCarpeta();//this method has a list with the routes to my files
for (int i = 0; i < lista.length; i++) {
int x = 0;
while (x < rutas.length) {
try{
String[] tmp;
FileInputStream fis = new FileInputStream(rutas[x]);
Scanner scanner = new Scanner(fis);
String line=scanner.nextLine();
do{
tmp=scanner.nextLine().split("\t");
if (lista[i].equals(tmp[9])) {
while(scanner.hasNextLine()){
do{
System.out.println(scanner.nextLine());
}while(tmp[0].equals("I"));
}
}
}while(scanner.hasNext() ) ;
scanner.close();
} catch (Exception e) {
} finally {
}
x++;
}
}
}
The variable line is unused, and is taking up a Scanner.nextLine(), you are effectively ignoring the first line of the file with this.
Next, in order to get your loop working correctly, you're gonna want to move the initialization of tmp outside of the loop. This ensures that no lines are skipped.
Finally, you need to update tmp inside the loop, and check it for starting character before displaying the line.
// extract the next line from the stream
tmp=scanner.nextLine().split("\t");
do{
// check if our number is in that line
if (lista[i].equals(tmp[9])) {
while(scanner.hasNextLine()){
do{
tmp=scanner.nextLine();
if(tmp[0].equals("I")) {
System.out.println(Arrays.toString(tmp));
}
}while(tmp[0].equals("I"));
}
}
}while(scanner.hasNext() ) ;
I've used Arrays.toString(tmp); here because it's the quickest way to show the result. You might want to consider reading every line into a string, and splitting it into another variable. That way you retain the string for display later.

JAVA My two-dimensional array scanned from a text file prints without the first column

I am working on a lab for school so any help would be appreciated, but I do not want this solved for me. I am working in NetBeans and my main goal is to create a "two-dimensional" array by scanning in integers from a text file. So far, my program runs with no errors, but I am missing the first column of my array. My input looks like:
6
3
0 0 45
1 1 9
2 2 569
3 2 17
2 3 -17
5 3 9999
-1
where 6 is the number of rows, 3 is the number of columns, and -1 is the sentinel. My output looks like:
0 45
1 9
2 569
2 17
3 -17
3 9999
End of file detected.
BUILD SUCCESSFUL (total time: 0 seconds)
As you can see, everything prints correctly except for the missing first column.
Here is my program:
import java.io.*;
import java.util.Scanner;
public class Lab3
{
public static void main(String[] arg) throws IOException
{
File inputFile = new File("C:\\Users\\weebaby\\Documents\\NetBeansProjects\\Lab3\\src\\input.txt");
Scanner scan = new Scanner (inputFile);
final int SENT = -1;
int R=0, C=0;
int [][] rcArray;
//Reads in two values R and C, providing dimensions for the rows and columns.
R = scan.nextInt();
C = scan.nextInt();
//Creates two-dimensional array of size R and C.
rcArray = new int [R][C];
while (scan.nextInt() != SENT)
{
String line = scan.nextLine();
String[] numbers = line.split(" ");
int newArray[] = new int[numbers.length];
for (int i = 1; i < numbers.length; i++)
{
newArray[i] = Integer.parseInt(numbers[i]);
System.out.print(newArray[i]+" ");
}
System.out.println();
}
System.out.println("End of file detected.");
}
}
Clearly, there is a logical error here. Could someone please explain why the first column is invisible? Is there a way I can only use my rcArray or do I have to keep both my rcArray and newArray? Also, how I can get my file path to just read "input.txt" so that my file path isn't so long? The file "input.txt" is located in my Lab3 src folder (same folder as my program), so I thought I could just use File inputFile = new File("input.txt"); to locate the file, but I can't.
//Edit
Okay I have changed this part of my code:
for (int i = 0; i < numbers[0].length(); i++)
{
newArray[i] = Integer.parseInt(numbers[i]);
if (newArray[i]==SENT)
break;
System.out.print(newArray[i]+" ");
}
System.out.println();
Running the program (starting at 0 instead of 1) now gives the output:
0
1
2
3
2
5
which happens to be the first column. :) I'm getting somewhere!
//Edit 2
In case anyone cares, I figured everything out. :) Thanks for all of your help and feedback.
Since you do not want this solved for you, I will leave you with a hint:
Arrays in Java are 0 based, not 1 based.
As well as Jeffrey's point around the 0-based nature of arrays, look at this:
while (scan.nextInt() != SENT)
{
String line = scan.nextLine();
...
You're consuming an integer (using nextInt()) but all you're doing with that value is checking that it's not SENT. You probably want something like:
int firstNumber;
while ((firstNumber = scan.nextInt()) != SENT)
{
String line = scan.nextLine();
...
// Use line *and* firstNumber here
Or alternatively (and more cleanly IMO):
while (scan.hasNextLine())
{
String line = scan.nextLine();
// Now split the line... and use a break statement if the parsed first
// value is SENT.

Taking input an arbitrary number of times

I am looking to solve a coding problem, which requires me to take the input an arbitary number of times with one integer at one line. I am using an ArrayList to store those values.
The input will contain several test cases (not more than 10). Each
testcase is a single line with a number n, 0 <= n <= 1 000 000 000.
It is the number written on your coin.
For example
Input:
12
2
3
6
16
17
My attempt to take input in Java:
List<Integer> list = new ArrayList<Integer>();
Scanner inp = new Scanner(System.in);
while(inp.hasNext()){
list.add(inp.nextInt());
}
However, when I try to print the elements of the list to check if I have taken the inputs correctly, I don't get any output. the corresponding correct code in C goes like this:
unsigned long n;
while(scanf("%lu",&n)>0)
{
printf("%lu\n",functionName(n));
}
Please help me fix this thing with Java.
(PS: I am not able to submit solutions in Java because of this )
You can do this one thing! At the end of the input you can specify some character or string terminator.
code:
List<Integer> list = new ArrayList<Integer>();
Scanner inp = new Scanner(System.in);
while(inp.hasNextInt())
{
list.add(inp.nextInt());
}
System.out.println("list contains");
for(Integer i : list)
{
System.out.println(i);
}
sample input:
10
20
30
40
53
exit
output:
list contains
10
20
30
40
53
Can you do something like this:
List<Integer> list = new ArrayList<Integer>();
Scanner inp = new Scanner(System.in);
while(inp.hasNextInt()){
list.add(inp.nextInt());
}
If there is some another value like character, loop finishes.

Categories