Inputting adjacency matrix from a file - java
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();
}
Related
The maximum product of adjacent elements in java
i am trying to print The maximum product of adjacent elements in an array but i am getting an error in my program: if input is [2, 5, 8, 9, 6] then desired output is : 72 import java.util.Scanner; class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int Product=0; int len = sc.nextInt(); int[] arr = new int[len]; for(int i=0; i < len; i++){ arr[i] = sc.nextInt(); } for(int i = 0; i<len-1; i++){ Product = arr[i]*arr[i+1]; int Nproduct = arr[i+1]*arr[i+2]; { if(Product<Nproduct){ Product = Nproduct; } } } System.out.println(Product); } } please help me where i am wrong. i am new here so please ignore my mistakes or edit if possible
There is some logical error as well as Run time error in your code. Take a Look at modified version of your code import java.util.Scanner; class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int Product=0; int len = sc.nextInt(); int[] arr = new int[len]; for(int i=0; i < len; i++){ arr[i] = sc.nextInt(); } for(int i = 0; i<len-1; i++){ if (arr[i]*arr[i+1]>Product){ Product=arr[i]*arr[i+1]; // update Product only if we get greater product } } System.out.println(Product); } }
your code needs some changes import java.util.Scanner; class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int Product=0; int len = sc.nextInt(); int[] arr = new int[len]; for(int i=0; i < len; i++){ arr[i] = sc.nextInt(); } for(int i = 0; i<len-1; i++){ if (arr[i]*arr[i+1]>Product){ Product=arr[i]*arr[i+1]; } } System.out.println(Product); } } for reference click here : GFG Problem
Change second loop for (int i = 0; i<len-1; i++) to for (int i = 0; i<len-2; i++) to prevent running out of upper array's bound
Reading data from file into 2d array
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; }
Condensing an adjacency matrix for shortest tour
I have a program that reads a data file and inputs the data as a 16 x 16 adjacency matrix. I need to find 10 nodes of the graph out of the 16 for which there is a minimal tour. Could someone show me how to implement a traveling salesperson algorithm that accomplishes this? I know how to do it for all 16 nodes, but I don't know how to condense it to only 10. 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 TSP(int[][] adjMat) { adjMat = new int[N][N]; } public static void main(String[] args) throws FileNotFoundException { File file = new File("american_tour.dat"); 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(); printGrid(adjMat); scanner.close(); } }
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); }
Java Selection Sort Confusion
I don't understand what is happening in this code. Re-post from before with code included. Can someone please explain what is happening here? I understand conceptually that the list is being re-ordered one item at a time, but I just cant grasp this code. import java.io*; public class Example { public static void main(String[] args) throws IOException { int age[] = new int[10]; int i, j; int smallest; int temp; String line; BufferedReader in; in = new BUfferedReader(new InputStreamReader(System.in)); for(i = 0; i<= 9; i++) { System.out.println("Enter an age: "); line = in.readline(); age[i] = Integer.valueOf(line).intValue(); } for(i = 0; i<= 9, i++) { smallest = i; for(j = 1; j<=9; j++) { if(age[j] < age[smallest]) { smallest = j; } } for (i = 0; i<=9; i++) { System.out.println(age[i]); } } } }
This looks like an implementation of the Bubble Sort. There is a wide wealth of information on the topic of this classic (and inefficient!) algorithm both on The Internet and in books on the subject of fundamental algorithms.
import java.io*; public class Example { public static void main(String[] args) throws IOException { int age[] = new int[10]; int i, j; int smallest; int temp; String line; BufferedReader in; in = new BUfferedReader(new InputStreamReader(System.in)); for(i = 0; i<= 9; i++) { System.out.println("Enter an age: "); line = in.readline(); age[i] = Integer.valueOf(line).intValue(); } for(i = 0; i<= 9, i++) { smallest = i; for(j = 1; j<=9; j++)// MISTAKE IS IN THIS LINE; YOU SHOULD START THE VALUE OF J FROM I+1(for(j = i+1; j<=9; j++))) { if(age[j] < age[smallest]) { smallest = j; } } //ALSO AFTER FINDING THE SMALLEST ELEMENT YOU HAVE TO SWAP THE SMALLEST ELEMENT WITH I ELEMENT /*int temp=age[i]; age[i]=age[smallest]; age[smallest]=temp*/ for (i = 0; i<=9; i++) { System.out.println(age[i]); } } } }