I have the following code:
List<String> l1_0 = new ArrayList<String>(), l2_0 = new ArrayList<String>(),.....;
List<Integer> l1_1 = new ArrayList<Integer>(), l2_1 = new ArrayList<Integer>()......;
int lines1 = 0, lines2 = 0, lines3 = 0 .....;
Scanner s1 = new Scanner(new FileReader("file/path//t1.txt"));
while (s1.hasNext()) {
l1_0.add(s1.next());
l1_1.add(s1.nextInt());
lines1++;
}
s1.close();
func1(l1_0,l1_1,lines);
I have to perform same operation for 40 files.
Can we create a for loop to achieve it?
I am thinking of something along the lines of.
for (int i=1; i<= 40 ; i++)
{
Scanner s[i] = new Scanner(new FileReader("file/path//t[i].txt"));
while (s[i].hasNext()) {
l[i]_0.add(s[i].next());
l[i]_1.add(s[i].nextInt());
lines[i]++;
}
s[i].close();
func1(l[i]_0,l[i]_1,lines[i]);
}
If I understood correctly, you want to loop over your data 40 times. Once for each file.
for (int i=0; i< 40 ; i++)
{
// Initializers for this one file
List<String> strings = new ArrayList<>();
List<Integer> nums = new ArrayList<>();
int lineCount = 0;
String filename = "t" + i;
try (Scanner s = new Scanner(new FileReader("file/path/" + filename + ".txt"))) {
while (s.hasNext()) {
strings.add(s.next());
if (s.hasNextInt()) {
nums.add(s.nextInt());
}
lineCount++;
}
}
func1(strings,nums,lineCount);
}
for (int i=1; i<= 40 ; i++){
Scanner s[i] = new Scanner(new FileReader("file/path//t[i].txt"));
}
In java there is no implicit String pattern resolution. That means you have to create yourself, the String representing new file names like this:
"file/path//t" + i + ".txt"
Or you may use String.format():
String.format("file/path//t%d.txt",i)
Related
I am given a text file as follows:
0:1,2,3
1:3
2:
3:2
I'm trying to read in from the file then add it to a singly linked list array. Here is what I have so far. I'm able to print out the first part of the file however struggling to print out the values following the ":".
Here is my code.
public static void main(String[] args) throws FileNotFoundException {
ArrayList<String> arrayList = new ArrayList<>();
Scanner sc = new Scanner(new File(args[0]));
while (sc.hasNextLine()) {
arrayList.add(sc.nextLine());
}
SinglyLinkedList singlyLinkedList[] = new SinglyLinkedList[arrayList.size()];
for (int i = 0; i < arrayList.size(); i++) {
String dag = arrayList.get(i);
String[] daglist = dag.split(":");
int listindex = Integer.parseInt(daglist[0]);
System.out.println(listindex + ":");
Thanks in advance
Here is the following code that I've tried.
public static void main(String[] args) throws FileNotFoundException {
ArrayList<String> arrayList = new ArrayList<>();
Scanner sc = new Scanner(new File(args[0]));
while (sc.hasNextLine()) {
arrayList.add(sc.nextLine());
}
SinglyLinkedList singlyLinkedList[] = new SinglyLinkedList[arrayList.size()];
for (int i = 0; i < arrayList.size(); i++) {
String dag = arrayList.get(i);
String[] daglist = dag.split(":");
int listindex = Integer.parseInt(daglist[0]);
System.out.println(listindex + ":");
// for (int j = 0; j < arrayList.size(); j++) {
// String[] daglist1 = dag.split(",");
// int listvalues = Integer.parseInt(daglist1[1]);
// System.out.println(listindex + ":" + listvalues + " ");
// }
}
}
This is giving me an infinite loop and not printing out correctly.
I have a .txt file that contains text that I would like to save part of it in a String, part of it in a String array, and then the last part in a 2D int array, and am faced with two issues:
How to read and save both of the arrays when their size is not known ahead of time?
2D array is not reading/saving properly
Here is the text file for reference:
This is the sentence to be read.
This
is
a
String
array.
90 47 110 95 95
101 87
54 0 38 12
Here is part of my method that is supposed to read and save the three data types:
BufferedReader br = new BufferedReader(new FileReader(fileName));
sentence = br.readLine();
stringArr = new String[5]; //how to initialize without set number of elements?
for(int i = 0; i<stringArr.length; i++){
stringArr[i] = br.readLine();
}
int2DArr = new int[3][5]; //how to initialize with any amount of rows and columns?
for(int i = 0; i<int2DArr.length; i++){
for(int j = 0; j<int2DArr[i].length; j++){
int2DArr[i][j] = br.read();
//how to read the space after each int ?
}
}
How would I "grab" the size of the arrays by reading the text file, so that when I initialize both arrays, I have the proper sizes? Any help would be greatly appreciated!
Instead of trying to achieve everything in a single pass we can pass through the file twice and obtain a neater code.
It will consume double time of course but it is going to help you understand how you could break bigger problems into smaller ones and deal with them one by one.
Here are the steps:
Determine size of stringArr and intArr in first pass
Fill value in respective array in second pass
If you are wondering how no of columns for int2DArr is determine. Simply we don't do it our self. We use the concept of Jagged Arrays
Read more here How do I create a jagged 2d array in Java?
import java.util.*;
import java.io.*;
class ReadFileIntoArr {
public static void main(String args[]) throws IOException {
String fileName = "test.txt";
BufferedReader br = new BufferedReader(new FileReader(fileName));
String line = br.readLine();
int strSize = 0;
int intSize = 0;
boolean isDigit = false;
while (line != null && line.trim().length() != 0) {
if (!isDigit && Character.isDigit(line.charAt(0)))
isDigit = true;
if (isDigit)
intSize++;
else
strSize++;
line = br.readLine();
}
br = new BufferedReader(new FileReader(fileName));
String[] stringArr = new String[strSize];
for (int i = 0; i < stringArr.length; i++)
stringArr[i] = br.readLine();
int[][] int2DArr = new int[intSize][];
for (int i = 0; i < int2DArr.length; i++)
int2DArr[i] = Arrays.stream(br.readLine().split(" ")).mapToInt(Integer::parseInt).toArray();
System.out.println(Arrays.toString(stringArr));
System.out.println(Arrays.deepToString(int2DArr));
}
}
Note: In single pass this could be accomplished with the help of ArrayList and later transfer everything into respective array.
Update: After understanding the constraints for your problem here is another version
import java.util.*;
import java.io.*;
class ReadFileIntoArr {
public static void main(String args[]) throws IOException {
String fileName = "test.txt";
BufferedReader br = new BufferedReader(new FileReader(fileName));
String line = br.readLine();
int strSize = 0;
int intSize = 0;
boolean isDigit = false;
while (line != null && line.trim().length() != 0) {
if (!isDigit && isDigit(line.charAt(0)))
isDigit = true;
if (isDigit)
intSize++;
else
strSize++;
line = br.readLine();
}
br = new BufferedReader(new FileReader(fileName));
String[] stringArr = new String[strSize];
for (int i = 0; i < stringArr.length; i++)
stringArr[i] = br.readLine();
int[][] int2DArr = new int[intSize][];
for (int i = 0; i < int2DArr.length; i++)
int2DArr[i] = convertStringArrToIntArr(br.readLine().split(" "));
System.out.println(Arrays.toString(stringArr));
System.out.println(Arrays.deepToString(int2DArr));
}
public static boolean isDigit(char c) {
return c >= '0' && c <= '9';
}
public static int[] convertStringArrToIntArr(String[] strArr) {
int[] intArr = new int[strArr.length];
for (int i = 0; i < strArr.length; i++)
intArr[i] = Integer.parseInt(strArr[i]);
return intArr;
}
}
Path path = Paths.get(fileName);
List<String> lines = Files.readAllLines(path, Charset.defaultCharset());
String title = lines.get(0);
List<String> words = new ArrayList<>();
for (int i = 1; i < lines.size(); ++i) {
String word = lines.get(i);
if (!word.isEmpty() && Character.isDigit(word.codePointAt(0)) {
break;
}
words.add(word);
}
String[] wordArray = words.toArray(new String[]);
int i0 = 1 + words.size();
int n = lines.size() - i0;
int[][] numbers = new int[n][];
for (int i = i0; i < lines.size(); ++i) {
String[] values = lines.get(i).trim().split("\\s+");
int m = values.length;
int[] row = new int[m];
for (int j = 0; j < m; ++m) {
row[j] = Integer.parse(values[j]);
}
numbers[i - i0] = row;
}
Path is a generalisation of File, also URLs.
Files is a treasure trove of file functions.
One could do without dynamically sized List; one would need to test first,
but normally one would use a List anyhow.
String.split splits on one or more whitespace.
All the examples that i have seen involve specifying the number of rows and columns at the start of the file but the method I'm working on reads a file with the following:
1.0 2.0
3.0 4.0
and using this data creates a 2d array and stores it without specifying the number of rows and columns.
Here's the code I have written:
public static double[][] readMatrixFrom(String file) throws FileNotFoundException {
Scanner input = new Scanner(new FileReader(file));
int rows =0;
int columns =0;
while(input.hasNextLine()){
String line = input.nextLine();
rows++;
columns = line.length();
}
double[][] d = new double[rows][columns]
return d;
}
I'm unsure of how to add these values now that I have created the 2d array. i tried this but got an InputMismatchException.
Scanner s1 = new Scanner(file);
double[][] d = new double[rows][columns]
for (int i= 0;i<rows;i++) {
for (int j= 0;i<rows;j++) {
d[i][j] = s1.nextDouble();
}
}
if you just want to use the basic arrays you can achieve it with something like
Scanner input = new Scanner(new FileReader(file));
int row=0;
int col =0;
String s="";
//count number of rows
while(input.hasNextLine()) {
row++;
s=input.nextLine();
}
//count number of columns
for(char c: s.toCharArray()) {
if(c==' ')
col++;
}
col++; // since columns is one greater than the number of spaces
//close the file
input.close();
// and open it again to start reading it from the begining
input = new Scanner(new FileReader(file));
//declare a new array
double[][] d = new double[row][col];
int rowNum=0;
while(input.hasNextLine()) {
for(int i=0; i< col; i++) {
d[rowNum][i]= input.nextDouble();
}
rowNum++;
}
However if you prefer to use java collection you can avoid reading the file again. Just store the strings in a list and iterate over the list to extract elements from it.
Based on your input, Your columns = line.length(); is returning 7 rather than 2 as it returns the String length.
Hence try calculating the no of columns in the row columns = line.split(" ").length;
Also while trying to read your input you were using index i for the 2nd for-loop. It should be like below,
for (int i= 0;i<rows;i++) {
for (int j= 0;j<columns;j++) {
d[i][j] = s1.nextDouble();
}
}
In order to work with arrays of unknown size you should read the data into a Collection (such as a List). However, Collection(s) only work with the wrapper-types; so you will need to copy the elements back into an array of double(s) if that is what you really need. Something like,
public static double[][] readMatrixFrom(String file) throws FileNotFoundException {
Scanner input = new Scanner(new FileReader(file));
List<List<Double>> al = new ArrayList<>();
while (input.hasNextLine()) {
String line = input.nextLine();
List<Double> ll = new ArrayList<>();
Scanner sc = new Scanner(line);
while (sc.hasNextDouble()) {
ll.add(sc.nextDouble());
}
al.add(ll);
}
double[][] d = new double[al.size()][];
for (int i = 0; i < al.size(); i++) {
List<Double> list = al.get(i);
d[i] = new double[list.size()];
for (int j = 0; j < d[i].length; j++) {
d[i][j] = list.get(j);
}
}
return d;
}
Which I tested by creating a file in my home folder with your contents and running it like so
public static void main(String[] args) {
String file = System.getProperty("user.home") + File.separator + "temp.txt";
try {
System.out.println(Arrays.deepToString(readMatrixFrom(file)));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
And I get (as I assume you wanted)
[[1.0, 2.0], [3.0, 4.0]]
I have the following code which counts and displays the number of times each word occurs in the whole text document.
try {
List<String> list = new ArrayList<String>();
int totalWords = 0;
int uniqueWords = 0;
File fr = new File("filename.txt");
Scanner sc = new Scanner(fr);
while (sc.hasNext()) {
String words = sc.next();
String[] space = words.split(" ");
for (int i = 0; i < space.length; i++) {
list.add(space[i]);
}
totalWords++;
}
System.out.println("Words with their frequency..");
Set<String> uniqueSet = new HashSet<String>(list);
for (String word : uniqueSet) {
System.out.println(word + ": " + Collections.frequency(list,word));
}
} catch (Exception e) {
System.out.println("File not found");
}
Is it possible to modify this code to make it so it only counts each occurrence once per line rather than in the entire document?
One can read the contents per line and then apply logic per line to count the words:
File fr = new File("filename.txt");
FileReader fileReader = new FileReader(file);
BufferedReader br = new BufferedReader(fileReader);
// Read the line in the file
String line = null;
while ((line = br.readLine()) != null) {
//Code to count the occurrences of the words
}
Yes. The Set data structure is very similar to the ArrayList, but with the key difference of having no duplicates.
So, just use a set instead.
In your while loop:
while (sc.hasNext()) {
String words = sc.next();
String[] space = words.split(" ");
//convert space arraylist -> set
Set<String> set = new HashSet<String>(Arrays.asList(space));
for (int i = 0; i < set.length; i++) {
list.add(set[i]);
}
totalWords++;
}
Rest of the code should remain the same.
BufferedReader inputStream = null;
String fileLine;
int employeeCount = 1;
String[] years = new String[2];
//Employee[] employees = new Employee[employeeCount + 1];
List<Employee> employees = new ArrayList<>();
File myFile = new File("src/project1/data.txt");
//System.out.println("Attempting to read from file in: "+ myFile.getCanonicalPath());
try {
FileInputStream fstream = new FileInputStream(myFile);
DataInputStream in = new DataInputStream(fstream);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String strLine;
while ((strLine = br.readLine()) != null) {
String[] data = strLine.split(" ");
//while ( int i < employees.length ) {
for (int i=1; i < employees.size(); i++ ) {
if (data[1].equals("Executive")) {
employees.add( new Executive(data[0],data[1],data[2], Integer.parseInt(data[3]), Integer.parseInt(data[4])) );
} else if (data[1].equals("Salesman")) {
employees.add( new Salesman(data[0],data[1],data[2], Integer.parseInt(data[3]), Integer.parseInt(data[4])) );
} else {
employees.add( new Employee(data[0],data[1],data[2], Integer.parseInt(data[3])) );
}
//System.out.println(employees[i].toString());
System.out.println(i +" " + employeeCount);
employeeCount++;
}
}
for (int y=1; y < employees.size(); y++ ) {
System.out.println(employees.get(y).getName());
}
//System.out.println(employees.toString());
} catch (IOException io) {
System.out.println("File IO exception" + io.getMessage());
}
EmployeeCount is incrementing as expected, but i is always 1 - what am I missing here? textfile is read in line by line using a while loop - for loop checks if second piece of data matches a string and creates object base on match. Am I making sense here?
The for loop is not incrementing because the condition is false after the first iteration at:
for (int i=1; i < employees.length; i++ ) {
that is, employees.length is 2 since employeeCount was one at this line (I must assume that since the code is incomplete):
Employee[] employees = new Employee[employeeCount + 1];
This line creates an array with two positions since employeeCount + 1 was 2. The size is not automatically adjusted as employeeCount is incremented...
I suggest using a List instead of an array, since the List is expanded as needed:
List<Employee> employees = new ArrayList<>();
...
employees.add(new Employee(...));