Reading data from file into 2d array - java

I need to read a file with a magic square in the format of:
#
# # #
# # #
# # #
where the first line represents the square size and create a 2d array with the file values.
I set up my readMatrix method to read through the lines, created a 2d array of the correct size and input each value to its correct position.
private int[][] readMatrix(String fileName) throws
FileNotFoundException {
int n;
File file = new File(fileName);
Scanner fileScan = new Scanner(file);
String line = fileScan.nextLine();
Scanner lineScan = new Scanner(line);
n = lineScan.nextInt();
square = new int[n][n];
while (fileScan.hasNextLine()) {
line = fileScan.nextLine();
while (lineScan.hasNext()) {
for (int i = 0; i < n; i++) {
lineScan = new Scanner(line);
for (int j = 0; j < n; j++) {
square[i][j] = lineScan.nextInt();
}
}
}
}
fileScan.close();
lineScan.close();
return square;
public int[][] getMatrix() {
int[][] copy;
int n = square.length;
copy = new int[n][n];
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
copy[i][j] = square[i][j];
}
}
return copy;
However the tester for this program displays a magic square of the correct dimensions but with all the values being 0 and fails the getMatrix method(I'm assuming because the returned square doesn't match the file square). I tried moving the scanner objects around(inside/outside) the for/while loops in the readMatrix and tried using parseInt/scan next instead of nextInt with no success. I am stumped.

Try this code is able to display 1 - 9 from the 3 x 3 matrix. The variable type can be changed to your need. I used 'char' for ease.
private static char[][] finalmatrix;
public static void main(String[] args) throws Exception {
finalmatrix = readMatrix("File.txt");
// Output matrix.
for (int i = 0; i < finalmatrix.length ;i++) {
for (int j = 0; j < finalmatrix[i].length ;j++) {
System.out.print(finalmatrix[i][j] + " ");
}
System.out.println("");
}
}
private static char[][] readMatrix(String fileName) throws IOException {
File file = new File(fileName);
Scanner scan = new Scanner(file);
int countRow = 0;
int countColumn = 0;
List temp = new ArrayList();
while (scan.hasNextLine()) {
String line = scan.nextLine();
for (int i = 0; i < line.length(); i++) {
// Count the number of columns for the first line ONLY.
if (countRow < 1 && line.charAt(i) != ' ') {
countColumn++;
}
// Add to temporary list.
if (line.charAt(i) != ' ') {
temp.add(line.charAt(i));
}
}
// Count rows.
countRow++;
}
char[][] matrix = new char[countRow][countColumn];
// Add the items in temporary list to matrix.
int count = 0;
for (int i = 0; i < matrix.length ;i++) {
for (int j = 0; j < matrix[i].length ;j++) {
matrix[i][j] = (char) temp.get(count);
count++;
}
}
scan.close();
return matrix;
}

Related

Fill a 2d array with text file, comma separated values

Hi i want to fill a 2d array with comma separated values like this
3
1,2,3
4,5,6
7,8,0
first number the size of the array, the next values are the values of the array this is my code at the moment
//readfile
public static void leeArchivo()
{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
try
{
//read first value which is teh size of the array
size = Integer.parseInt(br.readLine());
System.out.println("size grid" + size);
int[][] tablero = new int[size][size];
//fill the array with the values
for (int i = 0; i < tablero.length; i++)
{
for (int j = 0; j < tablero[i].length; j++ )
{
tablero[i][j] = Integer.parseInt(br.readLine());
}
}
br.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
This method is working fine for me, just another question, this will work if I want to insert another 2d array of the same size next to the other?
public static void leeArchivo()
{
Scanner s = new Scanner(System.in);
size = Integer.parseInt(s.nextLine());
tablero = new int[size][size];
boolean exit = false;
while (!exit) {
for (int i = 0; i < size; i++) {
//quit commas to fill array
String valuesStrArr[] = s.nextLine().split(",");
for (int j = 0; j < size; j++) {
tablero[i][j] = Integer.parseInt(valuesStrArr[j]);
}
if (i == size - 1)
exit = true;
}
}
}
Example:
3
1,2,3
4,5,6
7,8,0
1,2,3
8,0,4
7,6,5
Solution using Scanner
Scanner s = new Scanner(System.in);
int size = Integer.parseInt(s.nextLine());
int[][] tablero = new int[size][size];
boolean exit = false;
while (!exit) {
for (int i = 0; i < size; i++) {
String valuesStrArr[] = s.nextLine().split(",");
for (int j = 0; j < size; j++) {
tablero[i][j] = Integer.parseInt(valuesStrArr[j]);
}
if (i == size - 1)
exit = true;
}
}
Scanner in = new Scanner(System.in);
int num = in.nextInt();
Use Scanner. Replace System.in with File.
First, you have to separate the elements.
You can do this using the String method split (https://www.javatpoint.com/java-string-split)
//fill the array with the values
for (int i = 0; i < tablero.length; i++)
{
String[] elements = br.readLine().split(",");
for (int j = 0; j < tablero[i].length; j++ )
{
tablero[i][j] = Integer.parseInt(elements[j]);
}
}
br.close();
Or you can use Scanner method, nextInt.
Regarding perfomance, the first option is better.

Inputting adjacency matrix from a file

I am attempting to input the following file into my program in the form of an adjacency matrix.
16
-1,1075,716,792,1425,1369,740,802,531,383,811,2211,661,870,999,772
1075,-1,1015,1770,2403,1662,870,1858,941,1426,1437,3026,1486,211,1463,314
716,1015,-1,928,1483,646,390,1085,185,749,530,2034,1377,821,471,772
792,1770,928,-1,633,1089,1111,246,908,409,495,1447,1317,1565,672,1470
1425,2403,1483,633,-1,9999,1630,752,1432,9999,931,814,1938,2198,1016,2103
1369,1662,646,1089,9999,-1,820,1335,832,9999,605,1839,2030,1468,421,1419
740,870,390,1111,1630,820,-1,1224,360,965,690,2197,1480,750,630,705
802,1858,1085,246,752,1335,1224,-1,1021,442,737,1566,1190,1653,918,1558
531,941,185,908,1432,832,360,1021,-1,685,496,2088,1192,736,616,656
383,1426,749,409,9999,9999,965,442,685,-1,738,1858,1938,1221,926,1126
811,1437,530,495,931,605,690,737,496,738,-1,1631,1472,1232,188,1152
2211,3026,2034,1447,814,1839,2197,1566,2088,1858,1631,-1,2752,2824,1563,2744
661,1486,1377,1317,1938,2030,1480,1190,1192,1938,1472,2752,-1,1281,1660,1183
870,211,821,1565,2198,1468,750,1653,736,1221,1232,2824,1281,-1,1269,109
999,1463,471,672,1016,421,630,918,616,926,188,1563,1660,1269,-1,1220
772,314,772,1470,2103,1419,705,1558,656,1126,1152,2744,1183,109,1220,-1
However, I think I have something wrong with my logic or I'm not using the Scanner correctly. This is my code:
public class Tour
{
public static final int N = 16;
public static final int INF = Integer.MAX_VALUE;
public static void printGrid(int[][] adjMat)
{
for(int i = 0; i < 16; i++)
{
for(int j = 0; j < 16; j++)
{
if(adjMat[i][j] == INF)
System.out.printf("%5s", 0);
else
System.out.printf("%5d", adjMat[i][j]);
}
System.out.println();
}
}
public static void main(String[] args) throws IOException
{
File file = new File("american_tour.dat");
Scanner scanner = new Scanner(file);
int[][] adjMat = new int[N][N];
for(int i = 0, n = scanner.nextInt(); i < n; i++)
for(int j = 0; j < n; j++)
adjMat[i][j] = n;
scanner.close();
printGrid(adjMat);
}
}
Could someone show me how to properly input the data from the file into an adjacency matrix?
Improving Mouad's answer, using the scanner's built in support for custom delimiters:
Scanner scanner = new Scanner(file);
scanner.useDelimiter("[\\s,]+");
int N = scanner.nextInt();
int[][] adjMat = new int[N][N];
for(int i=0; i < N; i++) {
for (int j=0; j < N; j++) {
adjMat[i][j] = scanner.nextInt();
}
}
scanner.close();
As your data does not respect a specific pattern for delimiters, try this instead :
public static void main(String[] args) throws FileNotFoundException {
File file = new File("E:\\american_tour.dat");
Scanner scanner = new Scanner(file);
//N in the example equals 16
int N = scanner.nextInt();
//skip the first line
scanner.nextLine();
int[][] adjMat = new int[N][N];
for(int i = 0; i < N; i++){
String[] lines = scanner.nextLine().split(",");
for (int j=0; j<lines.length; j++) {
adjMat[i][j] = Integer.parseInt(lines[j]);
}
}
scanner.close();
}

How do i get characters in a file into a 2D array in Java?

So i have a file that looks like this:
+-+-+-+ ("/n")
|S| | ("/n")
+ + + + ("/n")
| |E| ("/n")
+-+-+-+ ("/n")
/n being a new line in the file
and i want to have each character here as an entry in a 5x7 array. I do not know how to do it, this is what i have tried (along with a lot of other things. input is the file):
public static void main(String[] args) throws FileNotFoundException {
Scanner input = new Scanner(new File("maze0.txt"));
char maze[][] = new char[5][7];
int charCount = 0;
for (int row = 0; row < finalHeight; row++) {
for (int col = 0; col < finalWidth; col++) {
while (input.hasNextLine()){
String line = input.nextLine();
if ((row < finalHeight - 1 || col < finalWidth) && charCount < line.length()) {
maze[row][col] = line.charAt(charCount);
charCount += 1;
System.out.print(maze[row][col]);
But this prints out +S+ + which is not right. I am a brand new beginner programmer and having a hard time with this, thanks for any help you can offer.
I fixed it!! this is what I did:
Scanner input = new Scanner(new File("maze0.txt"));
char maze[][] = new char[5][7];
input.nextLine();
for (int row = 0; row < 5; row++) {
String fileLine = input.nextLine();
for (int col = 0; col < 7; col++) {
char nextChar = fileLine.charAt(col);
maze[row][col] = nextChar;
System.out.print(maze[row][col]);
Actually, while the screen might display +S+ +, you only have one value in your array - at maze[0][0] (a value of '+'). Your while loop reads the entire file before the for loops ever increment.For each line it reads, it sets maze[row][column] = line.charAt(charCount); -- but row and column never get incremented because, well, there's another line to read. So it reads another line and overwrites maze[0][0] to be the line.charAt(1) (because you incremented charCount). This character is the space. Then it loops back through because there's another line to read, and puts the 3rd character at maze[0][0]. So on and so forth. When it's read the entire file, then it steps through the for loops, but while (input.hasNextLine()) doesn't execute because it's already read the entire file.
Here is a simple and efficient way to do it.
public static void main(String[] args) throws FileNotFoundException {
Scanner input = new Scanner(new File("maze0.txt"));
char maze[][] = new char[5][7];
for (int i = 0; i < maze.length; i++) {
//Get each line and convert to character array.
maze[i] = input.nextLine().toCharArray();
}
}
You can read each line from the file and convert it to char array.
public static void main(String[] args) throws IOException {
Scanner scan = new Scanner(new File("maze0.txt"));
String b;
char maze[][] = new char[5][7];
for (int row = 0; row < 5; row++) {
while ( scan.hasNextLine() ){
b = scan.nextLine();
maze[row] = b.toCharArray();
System.out.println(maze[row]);
}
}
scan.close();
}
you just need two loops why are you running 3 loops?
Scanner sc = new Scanner(new File("maze.txt"));
String line = null;
for(int i = 0; i< 5;i++)
{
line = sc.readLine()
for(int j = 0; j < 7; j++)
{
maze[i][j] = line.charAt(j);
}
}
This snippet should read the file and store it in a matrix.
Since you are reading the line in the inner loop, you are printing the diagonal.
Convert the line to character array using .toCharArray() That will give you an array of all the characters. Then just feed them into your array.
it'd look something like..
// everytime we come to a new row, read a line from the file, convert it into letters then proceed on feeding them into columns.
for (int row = 0; row < finalHeight; row++)
{
String line = input.nextLine();
Char[] chars = line.toCharArray();
if(!input.hasNextLine())
break; // if there is no more lines to read, break the loop.
for (int col = 0, i = 0; (col < finalWidth && i < chars.length); col++,i++)
{
maze[row][col] = chars[i];
System.out.print(maze[row][col]);
}
}
import java.io.*;
import java.util.*;
public class B
{
public static void main(String...aaadf)throws FileNotFoundException
{
Scanner sc = new Scanner(new File("D://maze.txt"));
char maze[][] = new char[5][7];
String line = null;
for(int i = 0; i< 5;i++)
{
line = sc.nextLine();
for(int j = 0; j < 7; j++)
{
maze[i][j] = line.charAt(j);
}
}
for(int i = 0; i< 5;i++)
{
for(int j = 0; j < 7; j++)
{
System.out.print(maze[i][j]);
}
System.out.println();
}
}
}

ways to speed up the Full Counting Sort

I encountered a question on hackerrank.
https://www.hackerrank.com/challenges/countingsort4
My first attempt passed all the test cases except the last one, due to timeout.
After failed to come up with a more efficient algorithm, I improved the code by using StringBuilder instead of concatenating Strings directly. This brought the running time from more than 5 sec to 3.5 sec.
My question is that is there any other way that I can improve the running time?
Thanks.
The following is my code.
public class Solution {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int N = scanner.nextInt();
scanner.nextLine();
int[] oriNum = new int[N];
String[] oriStr = new String[N];
int[] count = new int[100];
int[] indices = new int[100];
int[] output = new int[N];
// save the originals and the count array
for (int i = 0; i < N; i++) {
oriNum[i] = scanner.nextInt();
oriStr[i] = scanner.nextLine().trim();
count[oriNum[i]]++;
}
// accumulate the count array
indices[0] = 0;
for (int i = 1; i < 100; i++) {
indices[i] = indices[i-1] + count[i-1];
}
// output order
for (int i = 0; i < N; i++) {
int num = oriNum[i];
output[indices[num]++] = i;
}
int bar = N/2;
StringBuilder sb = new StringBuilder();
for (int i = 0; i < N; i++) {
int index = output[i];
if (index < bar)
sb.append("- ");
else
sb.append(oriStr[index]+ " ");
}
System.out.println(sb.toString());
}
}
You should try a plain buffered reader instead of Scanner. Scanner is surprisingly slow and I have participated in programming competitions where Scanner was the sole reason for "time limit exceeded".
import java.io.*;
import java.util.*;
import java.text.*;
import java.math.*;
import java.util.regex.*;
public class Solution
{
public static void main(String[] args)throws Exception
{
BufferedReader in=new BufferedReader(new InputStreamReader(System.in));
int n=Integer.parseInt(in.readLine());
int[] c=new int[100];
String[][] dt=new String[100][10300];
for(int i=0;i<n;i++)
{
String[] str=in.readLine().split(" ");
int val=Integer.parseInt(str[0]);
if(i<n/2)
dt[val][c[val]]="-";
else
dt[val][c[val]]=str[1];
c[val]++;
}
StringBuilder sb=new StringBuilder("");
for(int i=0;i<100;i++)
if(i<n)
for(int k=0;k<c[i];k++)
if(dt[i][k]!=null)
sb.append(dt[i][k]+" ");
else break;
System.out.println(sb.toString());
}
}
This was my approach to problem. (it is in c++).
void counting_sort(vector<int> &arr, int size, vector<vector<string> > foo, vector<int> first_half)
{
int max = *max_element(arr.begin(), arr.end());
int min = *min_element(arr.begin(), arr.end());
int range = max - min + 1;
int count[range] = {0};
// counting frequency of numbers in array
for (int i = 0; i < size; i++)
{
count[arr[i] - min]++;
}
// calculating cumulative sum
for (int i = 1; i < range; i++)
{
count[i] += count[i - 1];
}
vector<vector<string> > output(size);
// making the new sorted array
for (int i = size - 1; i >= 0; i--) // traversing from backward for stability
{
output[count[arr[i]-min] - 1] = foo[i];
count[arr[i]-min]--;
}
// copying the sorted array in original array
int j=0;
for (int i = 0; i < size; i++)
{
if(stoi(output[i][0]) == first_half[j])
{
cout << "- ";
j++;
}
else
{
cout << output[i][1] << ' ';
}
}
}
// Complete the countSort function below.
void countSort(vector<vector<string>> arr) {
vector<int> num;
vector<int> first_half;
for(int i=0; (unsigned)i<arr.size(); i++)
{
num.push_back(stoi(arr[i][0]));
if(i < ((unsigned)arr.size()/2))
{
first_half.push_back(stoi(arr[i][0]));
}
}
sort(first_half.begin(), first_half.end());
counting_sort(num, num.size(), arr, first_half);
}

how to get int[][] dimensionArray?

I want to get matrix[i][j] to my int[][] gettwodimensionalArray, I try so many way, but when I do the test, my gettwodimensionaArray still not store from matrix[i][j]. Please help me out, thank you.
Here is my code look like.
public int[][] gettwodimensionalArray(String file_name) {
File file = new File(file_name);
ArrayList<int[]> rows = new ArrayList<int[]>();
try {
Scanner scanner = new Scanner(file);
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
String[] s = line.split("\\s+");
int[] row = new int[s.length];
for (int i = 0; i < s.length; i++) {
row[i] = Integer.parseInt(s[i]);
}
rows.add(row);
System.out.println(line);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
int numbOfRow = rows.size();
// find number of columns by gettting the lenght of one of the rows row
int keepTrackSizeFirstRow;
for (int i = 0; i < numbOfRow; i++) {
if (i == 0) {
keepTrackSizeFirstRow = rows.get(0).length;
}
// compare current row i's array length, to keetracksizefirstrow
}
int[][] matrix = new int[numbOfRow][rows.get(0).length];
// System.out.println(matrix);
for (int i = 0; i < numbOfRow; i++) {
// i = row
for (int j = 0; j < rows.get(i).length; j++) {
// j = col
matrix[i][j] = rows.get(i)[j];
System.out.print(matrix[i][j]);
}
}
return matrix;
}
Not sure what you are trying to do. If you want each row of the input to fit in the array, you can declare the array with variable sizes, like this:
int[][] matrix = new int[numbOfRow][];
for (int i = 0; i < matrix.length; i++) {
matrix[i] = new int[rows.get(i).length];
}
If instead you want all rows to have the same length, you should find the maximum length of the input like this:
int maxlength = 0;
for (int i = 0; i < rows.size(); i++) {
maxlength = (rows.get(i).length > maxlength) ? rows.get(i).length : maxlength;
}
int[][] matrix = new int[numbOfRow][maxlength];

Categories

Resources