Reading a file into a multidimensional array - java

I want to read in a grid of numbers (n*n) from a file and copy them into a multidimensional array, one int at a time. I have the code to read in the file and print it out, but dont know how to take each int. I think i need to splitstring method and a blank delimiter "" in order to take every charcter, but after that im not sure. I would also like to change blank characters to 0, but that can wait!
This is what i have got so far, although it doesnt work.
while (count <81 && (s = br.readLine()) != null)
{
count++;
String[] splitStr = s.split("");
String first = splitStr[number];
System.out.println(s);
number++;
}
fr.close();
}
A sample file is like this(the spaces are needed):
26 84
897 426
4 7
492
4 5
158
6 5
325 169
95 31
Basically i know how to read in the file and print it out, but dont know how to take the data from the reader and put it in a multidimensional array.
I have just tried this, but it says 'cannot covernt from String[] to String'
while (count <81 && (s = br.readLine()) != null)
{
for (int i = 0; i<9; i++){
for (int j = 0; j<9; j++)
grid[i][j] = s.split("");
}

Based on your file this is how I would do it:
Lint<int[]> ret = new ArrayList<int[]>();
Scanner fIn = new Scanner(new File("pathToFile"));
while (fIn.hasNextLine()) {
// read a line, and turn it into the characters
String[] oneLine = fIn.nextLine().split("");
int[] intLine = new int[oneLine.length()];
// we turn the characters into ints
for(int i =0; i < intLine.length; i++){
if (oneLine[i].trim().equals(""))
intLine[i] = 0;
else
intLine[i] = Integer.parseInt(oneLine[i].trim());
}
// and then add the int[] to our output
ret.add(intLine):
}
At the end of this code, you will have a list of int[] which can be easily turned into an int[][].

private static int[][] readMatrix(BufferedReader br) throws IOException {
List<int[]> rows = new ArrayList<int[]>();
for (String s = br.readLine(); s != null; s = br.readLine()) {
String items[] = s.split(" ");
int[] row = new int[items.length];
for (int i = 0; i < items.length; ++i) {
row[i] = Integer.parseInt(items[i]);
}
rows.add(row);
}
return rows.toArray(new int[rows.size()][]);
}

EDIT: You just updated your post to include a sample input file, so the following won't work as-is for your case. However, the principle is the same -- tokenize the line you read based on whatever delimiter you want (spaces in your case) then add each token to the columns of a row.
You didn't include a sample input file, so I'll make a few basic assumptions.
Assuming that the first line of your input file is "n", and the remainder is the n x n integers you want to read, you need to do something like the following:
public static int[][] parseInput(final String fileName) throws Exception {
BufferedReader reader = new BufferedReader(new FileReader(fileName));
int n = Integer.parseInt(reader.readLine());
int[][] result = new int[n][n];
String line;
int i = 0;
while ((line = reader.readLine()) != null) {
String[] tokens = line.split("\\s");
for (int j = 0; j < n; j++) {
result[i][j] = Integer.parseInt(tokens[j]);
}
i++;
}
return result;
}
In this case, an example input file would be:
3
1 2 3
4 5 6
7 8 9
which would result in a 3 x 3 array with:
row 1 = { 1, 2, 3 }
row 2 = { 4, 5, 6 }
row 3 = { 7, 8, 9 }
If your input file doesn't have "n" as the first line, then you can just wait to initialize your final array until you've counted the tokens on the first line.

Related

My loop is populating my array with the number seven, 6 times, why?

Im writing a program to read in a file and store the strings in arraylist and ints in an array. The file contains strings and ints in the format: String int
I have already got the string section to work, I'm looking to know why the following code is populating my array with the number 7, six times rather than the correct numbers.
Correct output would be:
12, 14, 16, 31, 42, 7
But it gives:
7, 7, 7, 7, 7, 7
Code:
BufferedReader buffy = new BufferedReader(new FileReader(fileName));
while((str = buffy.readLine()) != null) {
for(int i = 0; i <= arrayInt.length - 1; i++) {
for(int k = 0; k <= str.length()-1; k++) {
if(str.substring(k, k + 1).equals(" ")) {
String nums = str.substring(k+1);
arrayInt[i] = Integer.parseInt(nums);
}
}
}
}
buffy.close();
This happens because for each line in file you fill whole array.
Try this:
int i = 0;
BufferedReader buffy = new BufferedReader(new FileReader(fileName));
while((str = buffy.readLine()) != null) {
if(i < arrayInt.length) {
for(int k = 0; k <= str.length()-1; k++) {
if(str.substring(k, k + 1).equals(" ")) {
String nums = str.substring(k+1);
arrayInt[i] = Integer.parseInt(nums);
break;
}
}
i++;
}
}
buffy.close();
Also you can use indexOf
int i = 0;
BufferedReader buffy = new BufferedReader(new FileReader(fileName));
while((str = buffy.readLine()) != null) {
if(i < arrayInt.length) {
int k = str.indexOf(" ");
if(k!=-1) {
String nums = str.substring(k+1);
arrayInt[i] = Integer.parseInt(nums);
}
i++;
}
}
buffy.close();
File read are typically batch/ETL kind of job and if this code is going to production and would be used multiple times instead of only once then I would like to stress on Performance and Ease of Maintenance:
Only read least characters to identify the space index
#talex added a very good line of code i.e. break; inside the loop that way you won't need to read till the end of line but this would only work if the string has no spaces. If the string can contain spaces than you would need lastIndexOf space (" ") or no break; at all.
I prefer using framework method lastIndexOf assuming you are using java because:
it would start reading from right instead of left and assuming the numbers would be always less length than the string it would find index of space faster in most of the cases than reading from start.
2nd benefit is that there are lots of scenarios framework/utilities method already handled so why to reinvent the wheel
int k = str.lastIndexOf(" ");
last but not the least if someone else is going to maintain this code it would be easier for him/her as there would be enough documentation available.
Only read required lines from files
Seems like you only need certain number of lines to read arrayInt.length if that's the case then you should 'break;' the while loop once the counter i is more than array length.
I/O operations are costly and though you will get right output you would end-up scanning whole file even if it's not required.
Dont forget try-catch-finally
The code assumes that there will not be any issue and it would be able to close the file after done but there could be n number of combinations that can result in error resulting the application to crash and locking the file.
See the below example:
private Integer[] readNumbers(String fileName) throws Exception {
Integer[] arrayInt = new Integer[7];
String str = null;
BufferedReader buffy = new BufferedReader(new FileReader(fileName));
try {
int i=0;
while ((str = buffy.readLine()) != null) {
if(i> arrayInt.length){
break;
}
//get last index of " "
int k = str.lastIndexOf(" ");
if(k > -1){
String nums = str.substring(k+1);
arrayInt[i] = Integer.parseInt(nums);
}
//increment the line counter
i++;
}
} catch (Exception ex) {
//handle exception
} finally {
buffy.close();
}
return arrayInt;
}

trying to print transpose string[]

So i've been trying to take a txt file which has input like this for eg -
abcddhdj
efghdd
ijkl
to get this -
j
d
hd
dd
dhl
cgk
bfj
aei
i have tried to do this using 2d char array which gave nullexception and arrayoutofbound error and didnt work mostly,then tried string array , arraylist of arraylist of char , and lastly i have been trying using arraylsit of string
here is the closest i got to my solution after lot of searching by using string[] -
public static void main(String[] args) throws IOException
{
BufferedReader br = new BufferedReader(new FileReader("C:\\test.txt")); // PUT YOUR FILE LOCATION HERE
int k=0,i,j=0,x;
String line[] = new String[10] ; //SET THE APPROXIMATE NUMBER OF ROWS
while((line[k] = br.readLine()) !=null)
{System.out.println(line[k]); //print to check input - verified
k++;
}
for(x=0;x<k;x++)
{if(j<line[x].length())
{j=line[x].length()-1;} //this part not working in above loop
}
System.out.println(j); // verified but not working inside previous loop for some reason
System.out.println(k);
for(x=j-1;x>=0;x++) //without this loop,its perfect, but with it gives indexoutofbound error , doesnt run at x=j
{ for(i=0;i<k;i++)
{ System.out.print(line[i].charAt(x));
}
System.out.println();
}
}
here is one output
run:
abcd
efgh
ijkl
4 //should have come as 3 since i did length-1
3
chl //notice the d missing , every char of first row shifted,just why
bgk //in outofbound error , it only prints d at the end, need explanation
afj
ei
BUILD SUCCESSFUL (total time: 0 seconds)
if i add a space after abcd it gives indexoutofbound and no output after k
at end i used another method which adds spaces to make all length equal
yet still the output was wrong, plus there is something wrong with this way of thinking , there should be better method
so i tried arraylist , this is giving me more problems again
trying to work this out by any method understandable.
This ought to do the trick:
The key here is that I pad all the line arrays with empty chars so that each character array is the same length as the longest line.
public static void main(String[] args)
{
try (BufferedReader br = new BufferedReader(new FileReader("C:\\test.txt")))
{
String line;
List<List<Character>> lines = new ArrayList<>();
int longestLine = 0;
while((line = br.readLine()) !=null)
{
line = line.trim();
if (line.length() > 0)
{
List<Character> currList = new ArrayList<>();
for (char c : line.toCharArray())
{
currList.add(c);
}
if (currList.size() > longestLine)
{
longestLine = currList.size();
}
lines.add(currList);
}
}
// pad all lists to be the same as the longest
for (List<Character> currList : lines)
{
while (currList.size() < longestLine)
{
currList.add(Character.MIN_VALUE);
}
}
// go through each list backwards
for (int i = longestLine - 1; i >= 0; i-- )
{
for (List<Character> currList : lines)
{
System.out.print(currList.get(i));
}
System.out.println();
}
}
catch (Throwable t)
{
t.printStackTrace();
}
}
Example Input:
abcd
efgh
ijkl
g
Example Output:
dhl
cgk
bfj
aeig
Assuming input is read into the arraylist
ArrayList<String> inputList = new ArrayList<String>();
inputList.add("abcddhdj");
inputList.add("efghdd");
inputList.add("ijkl");
int maxSize = 0;
for (String input : inputList) {
if (input.length() > maxSize) {
maxSize = input.length();
}
}
String outputList[] = new String[maxSize];
for (int i = 0; i < maxSize; i++) {
String output = "";
for (String input : inputList) {
if(i<input.length())
output=output+input.charAt(i);
}
outputList[maxSize-(i+1)]=output;
}
Store all to direct 2d array and transpose in printing loop
final char[][] matrix = Files.lines(Paths.get(fileName)).map(String::toCharArray).toArray(char[][]::new);
final int width = Arrays.stream(matrix).mapToInt(a -> a.length).max().getAsInt();
for (int i = 0; i < width; ++i ) {
final int idx = width-i-1;
String s = Arrays.stream(matrix).map(a -> a.length > idx ? String.valueOf(a[idx]) : " ").collect(Collectors.joining());
System.out.println(s);
}

Java 2d Array unable to edit value and properly return element back null values

My knowledge with java language is very new. Most of my knowledge are from googling up on how to do things. I've been working on a console program in java that uses a switch statement. The entire program utilizes an String [20][5] array. I've written the code to now be able to add entry, save array to file, load entries from file into the array.
The problems now is edit and removing entries. I am able to return values to null but it'll look like this [[null], [null, null, null, null, null].
I want the value to return to [null, null, null, null, null], [null, null, null, null, null].
The Edit entry some reasons return an java.lang.ArrayIndexOutOfBoundsException:1 .
Could someone point out my error? Also the Array is globally declare.
public static String[][] rem(){
Scanner input = new Scanner(System.in);
int x,y=0;
//for(int i=0;i<array.length;i++){
//if(array[i][0]!=null){
System.out.println(Arrays.deepToString(array));//}
//}
System.out.println("Which entry would you like to remove? "
+ "\n" + "Enter number 0 - 20");
x = input.nextInt();
array[x][y]=null;
return array;}
public static String[][] edit(){
Scanner input = new Scanner(System.in);
String k;
int j;
int g;
// for(int i=0;i<array.length;i++){
//if(array[i][0]!=null){
//System.out.println(Arrays.deepToString(array));}
//}
System.out.println("Which entry would you like to edit? "
+ "\n" + "Enter number 0 - 20");
j = input.nextInt();
System.out.println("What would you like to edit? "
+"\n" + "Enter number 0 - 5");
g = input.nextInt();
System.out.println("You are now editing.");
k = input.next();
array[j][g] = k;
return array;}
Update
I think I figure my issue. The array properly edit values I manually input. It's when I load data into the array that causes problem because when it loads data it loads as String []. I need a code that will load the data as String[][] or as array of arrays.
public static String[][] load()throws FileNotFoundException, IOException{
menu();
copyFile();
String file = ("c:/temp/Address.txt");
Scanner scan = new Scanner(new FileReader(file));
// initialises the scanner to read the file file
//String[][] entries = new String[100][3];
// creates a 2d array with 100 rows and 3 columns.
//int i = 0;
while(scan.hasNextLine()){
array[i][i] = scan.next().split("," , "\t");
i++;
}
//loops through the file and splits on a tab
//for (int row = 0; row < array.length; row++) {
// for (int col = 0; col < array[0].length; col++) {
// if(array[row][col] != null){
// System.out.print(array[row][0] );
// }
// }
// if(array[row][0] != null){
// System.out.print("\n");
//}
// }
//prints the contents of the array that are not "null"
selectMenu();
return array;}
Update 2
I have found the solution to solving the loading data issue. The solution is simple! I'll leave the code here for reference. Though, all of the codes could use some beautifying.
public static String[][] load()throws FileNotFoundException, IOException{
menu();
copyFile();
String file = ("c:/temp/Address.txt");
Scanner scan = new Scanner(new FileReader(file));
FileReader fr = new FileReader("c:/temp/Address.txt");
BufferedReader br = new BufferedReader(fr);
//int j=0;
//int lineNo = 0;
//String line = br.readLine();
//while(line!=null)
//{
//for(int i = 0; i < 5; i++)
//{
//array[lineNo][i] = line.substring(i,4);
//}
// lineNo++;
//line = br.readLine(); // This is what was missing!
//}
//while(scan.hasNextLine()){
//while(scan.hasNext()){
//for(j=0;j<5;j++){
for(int i = 0; i < 20; ++i){
for(int j = 0; j < 5; ++j)
{
if(scan.hasNext())
{
array[i][j] = scan.next();
//i++;
//j++;
}
//i++;
}
}
selectMenu();
return array;}
Update 3
So after figuring out on how to use the delimiter it sorts of give me a weird issue. It adds return at the end of the column. [null, null, null, null, null return]. I used ",|\n" as my delimiter. Is there a better method? Update: Added a .trim(); solve the final issue with load. Now it's perfected in its current job. Though, I'm sure there might be less primitive methods.
public static String[][] load()throws FileNotFoundException, IOException{
copyFile();
//delimiter removes the comma or return to the next line. "\n" new line
Scanner scan = new Scanner(new FileReader(file)).useDelimiter(",|\n");
for(int i = 0; i < 20; ++i){
for(int j = 0; j < 5; ++j){
if(scan.hasNext())
array[i][j] = scan.next().replace(",", "").trim();
}
}
System.out.println("File loaded successfully!!");
scan.close();
return array;}
This is an off by one error, very subtle mistake:
Although you have 20 rows and 5 columns, arrays use a 0 based index(start counting from 0 instead of 1).
Use your fingers to count from 0 - 5 and you will see that there are actually 6 numbers instead of 5 which is causing your OutOfBoundsException as you don't have a 6th element.
Therefore to access your rows and columns, the range should be between:
0 - 19 (for the columns) and 0 - 4 (for the rows)
Or
1 - 20 (for the columns) and 1 - 5 (for the rows) and then subtract 1 from your scanners input since remember arrays use 0 based index.
update for the file reading:
public static String[][] load() {
try{
FileReader fr = new FileReader("c:/temp/Address.txt");
BufferedReader bf = new BufferedReader(fr);
String presentLine = "";
for(int i = 0; i < 20; i++) {
for(int j = 0; i < 5; j++) {
if ((presentLine = bf.readLine()) != null) {
array[i][j] = presentLine;
}
}
}
} catch(Exception e) {
System.out.println(e);
}
selectMenu();
return array;
}
Although this could be made way better but it's okay.
You could store 20 and 5 as static variables called rows and columns respectively to avoid using hard coded numbers.

I want to Copy the Largest number from one file to another File?But,I get some problems while inputting the numbers

Whenever I try to write the Numbers like this-
(1
2
3
4
56)
It takes only the first number.What is wrong with my code.This is my code.
BufferedReader out = new BufferedReader(new FileReader("Nos for finding highest.txt"));
PrintWriter in = new PrintWriter(new FileWriter("third.txt"));
String str = " ";
str = out.readLine();
String[] numbers = str.split("\n");
int[] array = new int[numbers.length];
int count = 0;
for (String strs : numbers) {
array[count++] = Integer.parseInt(strs);
}
int max = array[0];
for (int c : array) {
if (c > max)
max = c;
}
in.println(new Integer(max).toString());
in.close();
out.close();
If I take while((str = out.readLine()) != null) in the above code then it printouts all the numbers instead of printing max(Largest Number).
I'll expand on my comment for formatting reasons: Assuming your file has one number per line you'll want to first read them all into a list:
List<Integer> list = new LinkedList<>();
while((str = out.readLine()) != null) {
//assuming the line is not empty and contains a valid integer
list.add( Integer.valueOf(str) );
}
Then iterate and look for the highest number:
for( Integer i : list ) {
//check for max here
}
If you input the numbers are on on the same line then split the input using space:
String[] numbers = str.split(" ");
If your numbers in the file are each in new line then use
String[] numbers = str.split("\n");

Java, input file to 2D array

I'm really new to Java. I'm trying to take values from an input file, which I made in eclipse, and trying to save them to a 2D array. The input is:
31 22 23 79
20 -33 33 1
3 -1 46 -6
I can save it to a regular array fine, but not matter what I try I can't figure out how to get it to save to a 2d array in the form above. I tried for loops, but it saved all 12 numbers for each iteration of the loop. I tried using variables and just incrementing them like for the regular array and it just saved nothing. Any help on how to do this appreciated, code for regular array is below, prints the following to screen:
[31, 22, 23, 79, 20, -33, 33, 1, 3, -1, 46, -6]
import java.io.*;
import java.util.Arrays;
import java.util.StringTokenizer;
public class ArrayMatrix2d {
public static void main(String[] args) {
// TODO Auto-generated method stub
if (args.length == 0){
System.err.println("Usage: java Sum <filename>");
System.exit(1);
}
try {
//int[][] matrix = new int[3][4];
int MyMat[] = new int[12];
int num = 0;
//int row = 0;
//int column = 0;
BufferedReader br = new BufferedReader(new FileReader(args[0]));
String line;
while((line = br.readLine()) != null) {
StringTokenizer st = new StringTokenizer (line);
while (st.hasMoreTokens()){
int value1 = Integer.parseInt(st.nextToken());
MyMat[num] = value1;
num++;
}
}
System.out.println(Arrays.toString(MyMat));
br.close();
}
catch(Exception e) {}
}
}
You could make your matrix like this
int[][] matrix=new int[3][]; //if the number of columns is variable
int[][] matrix=new int[3][4]; //if you know the number of columns
and in the loop you get
int i=0;
while((line = br.readLine()) != null) {
StringTokenizer st = new StringTokenizer (line);
int num=0;
//the next line is when you need to calculate the number of columns
//otherwise leave blank
matrix[i]=new int[st.countTokens()];
while (st.hasMoreTokens()){
int value1 = Integer.parseInt(st.nextToken());
matrix[i][num] = value1;
num++;
}
i++;
}
If you use Java 7 you can load text file to List. As I know this is a shortest way to create String[][]
String[][] root;
List<String> lines = Files.readAllLines(Paths.get("<your filename>"), StandardCharsets.UTF_8);
lines.removeAll(Arrays.asList("", null)); // <- remove empty lines
root = new String[lines.size()][];
for(int i =0; i<lines.size(); i++){
root[i] = lines.get(i).split("[ ]+"); // you can use just split(" ") but who knows how many empty spaces
}
Now you have populated root[][]
Hope it will help you
With hope, that my code will be useful for you:
java.util.Scanner scan = new java.util.Scanner(System.in);
int [] ar= Arrays.stream(scan.nextLine().split(" ")).mapToInt(Integer::parseInt).toArray();
int m=ar[0];
int n=ar[1];
int myArray[][]=new int[m][n];
for (int i = 0; i < m; i++)
myArray[i]= Arrays.stream(scan.nextLine().split(" ")).mapToInt(Integer::parseInt).toArray();

Categories