Processing range of lines in a 2d array or file - java

I'm very new to programming. I'm studying on my own, and the examples from the book I'm using are too easy so I'm trying to do something harder. Lotteries are one of my hobbies and I think the problem I chose will make it easier for me to learn Java.
This program calculates frequencies (how many times each number from 1 t0 70 appears in my txt file) in Keno, a type of lottery(In Keno, a draw consists of 20 numbers out of 70, instead of the widespread 6 out of 49).
I want to calculate the frequencies not for the entire txt file, but just for a section of it, for example if the file has x lines, I want just the lines between x-5 and x-10, something like this.I don't know the number of lines in my file, perhaps thousands, but it always has 20 columns.
The program works fine for the entire file, but I run into trouble when trying to work just on a section of it. I think that I should read the file into a 2d array and then I could process the lines I want. I'm having hard times transferring every line into a matrix. I've read every post regarding reading a file into a 2d array but couldn't make it work.
Below is one of the many attempts I made over more than a week
public static void main(String args[]) {
int[][] matricea = new int [30][40];
int x=0, y=0;
try {
BufferedReader reader = new BufferedReader(
new FileReader("C:\\keno.txt")
);
int[] numbers = new int[72]; //each keno draw has 70 numbers
for (int i = 0; i < 71; i++ ){
numbers[i] = 0;
}
int k=0; // k counts the lines
String draw;
while ( (draw = reader.readLine()) != null ) {
String[] pieces = draw.split(" +");
k++;
for (String str : pieces) {
int str_int = Integer.parseInt(str);
matricea[x][y] = str_int;
System.out.print(matricea [x][y] + " ");
y = y + 1;
}
x = x + 1;
System.out.println(" ");
}
for (int j = 1; j <= 20; j++) {
int drawnNumber = Integer.parseInt(pieces[j]);
numbers[drawnNumber]++;
}
System.out.println(" nr. of lines is " + k);
reader.close();
for (int i = 0; i < 71; i++) {
System.out.println(i + ": " + numbers[i]);
}
} catch (Exception e) {
System.out.println("There was a problem opening and processing the file.");
}
}

Formatting and improving current code
I'll show how to solve your problem, but first I would like to point out a few things in your code that could be improved by some formatting, or that perhaps are unnecessary.
Just to help you improve your coding skills, readability is very important! :)
And don't forget, consistency is key! If you like one style better than the more common style, or the preferred style, that's fine as long as you use it throughout your coding. Don't switch between two styles.
If you don't care to read these comments, you can find the solution at the bottom of my answer. Just note that your original code will be different in my solution because I have formatted it to be most readable for me.
Spacing in variable declarations
Original code
int[][] matricea = new int [30][40];
int x=0, y=0;
Spacing modified
int[][] matricea = new int[30][40];
int x = 0, y = 0;
Notice the space removed between int and [30][40], and the space added between the variables and the initialization, i.e. - x=0 => x = 0.
Initializing an int array to contain all 0's
Original code
int[] numbers = new int[72]; //each keno draw has 70 numbers
for (int i = 0; i < 71; i++ ){
numbers[i] = 0;
}
Same as
int[] numbers = new int[72]; //each keno draw has 70 numbers
You don't have to set each value to 0, Java will do that for you. In fact, Java has default values, or null values, for all types. Thanks to Debosmit Ray!
I won't go into the exceptions to this case, or when or why or how, you can read about that in this post, and pay close attention to Aniket Thakur's answer.
But why do you have an array of size 72, if there are only 70 possibilities?
Choosing variable names
Original code
int k=0; // k counts the lines
Same as
int numLines = 0;
You should always make your variables names something meaningful to their purpose. If you ever have to put a comment like k counts the lines to describe a variable's purpose, consider if a better name would work instead.
Functionalizing code
Original code
while ( (draw = reader.readLine()) != null ) {
String[] pieces = draw.split(" +");
k++;
for (String str : pieces) {
int str_int = Integer.parseInt(str);
matricea[x][y] = str_int;
System.out.print(matricea [x][y] + " ");
y = y + 1;
}
x = x + 1;
System.out.println(" ");
}
Same as
while ( (draw = reader.readLine()) != null ) {
processLine(draw);
}
Of course, you'll have to make the method processLine(String line), but that won't be hard. It's just taking what you have and moving it to a separate method.
The original code's while loop is very busy and messy, but with the latter option makes the purpose clear, and the code clean.
Of course each situation is different, and you might find that only removing part of the code into a method would be a better solution. Just play around and see what makes sense.
Error!
Original code
for (int j = 1; j <= 20; j++) {
int drawnNumber = Integer.parseInt(pieces[j]);
numbers[drawnNumber]++;
}
This code should not work, since pieces is declared in the while loop above it, and is local to that above loop. This for loop is outside the scope of where pieces exists.
I'll tell you how to fix it, but I'm not sure what the code is supposed to be doing. Just let me know what its purpose is, and I'll provide you with a solution.
After formatting!
This is what the code may look like after applying my above comments. I have added comments to parts that I have changed.
public static void main(String args[]) {
try {
doKenoStuff();
} catch(IOException e) {
System.out.println("There was a problem opening and processing the file.");
}
}
public static void doKenoStuff() throws IOException {
BufferedReader reader = new BufferedReader(
new FileReader("C:\\keno.txt")
);
int[][] matricea = new int[30][40];
int[] numbers = new int[72]; //each keno draw has 70 numbers
// We can clean up our loop condition by removing
// the assignment (draw = reader.readLine) from it.
// Just make sure draw doesn't begin as null.
String draw = "";
int row;
for(row = 0; draw != null; row++) {
draw = reader.readLine();
// We read a line from the file, then send it
// to extractLineData which will collect the info
// from each column, and update matricea and numbers
extractLineData(draw, row, matricea, numbers);
}
System.out.println("Number of lines: " + row);
System.out.println("Each number's drawing stats:");
for (int i = 0; i < 71; i++) {
System.out.println(i + ": " + numbers[i]);
}
reader.close();
}
public static void extractLineData(String line, int row, int[][] matrix, int[] numbers) {
String linePieces = line.split(" +");
for(int column = 0; column < linePieces.length; column++) {
int number = Integer.parseInt(linePieces[column]);
matrix[row][column] = number;
numbers[number]++;
}
}
Solution
Note: I am not perfect, and my code is not either. I'm not trying to say that what I have suggested is in any way the only way to do this. It could definitely be improved, but it is a start. You should take my solution and see how you can improve it yourself.
What can you find that you could code in a cleaner, or faster, or better way?
So, how do we fix the problem?
We have a method that reads from the start of a file, to the end of it, and it logs the data it finds inside matricea.
A quick and easy solution is to simply make that method take in two parameters, a starting line number, and an ending line number.
public static void doKenoStuff(int start, int end) throws IOException {
Then we simply make a loop to skip over the starting lines! It's that easy!!!
for(int i = 0; i < start - 1; i++) {
reader.readLine();
}
Don't forget that we may not need the big 30 row matricea to be 30 rows anymore. We can shrink that down to end - start + 1. That way, if a user wants to read from line 45 to line 45, we only need 45 - 45 + 1 = 1 row in matricea.
int[][] matricea = new int[end - start + 1][40];
And the very last thing we need to add is a condition in our line reading loop, that prevents us from going past the ending line.
for(row = 0; draw != null, row <= end; row++) {
And there you have it. Simple as that!
Complete solution
public static void main(String args[]) {
int start = 7, end = 18;
try {
doKenoStuff(start, end);
} catch(IOException e) {
System.out.println("There was a problem opening and processing the file.");
}
}
public static void doKenoStuff(int start, int end) throws IOException {
BufferedReader reader = new BufferedReader(
new FileReader("C:\\keno.txt")
);
int[][] matricea = new int[end - start + 1][40];
int[] numbers = new int[72]; //each keno draw has 70 numbers
for(int i = 0; i < start - 1; i++) {
reader.readLine();
}
String draw = "";
int row;
for(row = 0; draw != null, row <= end; row++) {
draw = reader.readLine();
extractLineData(draw, row, matricea, numbers);
}
System.out.println("Number of lines: " + row);
System.out.println("Each number's drawing stats:");
for (int i = 0; i < 71; i++) {
System.out.println(i + ": " + numbers[i]);
}
reader.close();
}
public static void extractLineData(String line, int row, int[][] matrix, int[] numbers) {
String linePieces = line.split(" +");
for(int column = 0; column < linePieces.length; column++) {
try {
int number = Integer.parseInt(linePieces[column]);
matrix[row][column] = number;
numbers[number]++;
} catch (NumberFormatException) {
// You don't have to do anything in this block, but
// you can print out what input gave the exception if you want.
System.out.println("Bad input: \"" + linePieces[column] + "\"");
}
}
}

Related

turning an array of strings into a 2d array of chars

my code reads input from a file that has a maze written inside, inside the file looks like this.
7 7
GOOOOXO
XXOXOOX
OXOOOXX
XXXOOXO
XXXXOXX
SOOOOOX
XXXXXXX (these are each on a separate line not sure how to show that here)
the numbers are the dimensions and G is goal S is start, that doesn't really matter for now. I read the file into an array of Strings line by line. So my array looks like this {"GOOOOXO",...,"XXXXXXX"} now I want to convert the strings to a 2d array of chars where the characters are stored the same way as the maze is displayed above.
The first nested for loop just reads the files input and saves each line as a string in the array, the second array is meant to convert the strings into characters to save them into the 2d array and still manage to keep the shape of the maze. I get an array index out of bounds exception. But to be honest with you after hours of being stuck on this my brain is fried, I can't figure out my issue.
int dimensionsX = input.nextInt();
int dimensionsY = input.nextInt();
String[] lines = new String[dimensionsY];
char[][] maze2 = new char[dimensionsX][dimensionsY];
for (int j = 0; j < dimensionsY; ++j) {
if (input.hasNextLine()) {
lines[j] = input.nextLine();
System.out.println(lines[j]);
//System.out.println(j);
}
}
for (int i = dimensionsX; i > 0; --i) {
for (int j = dimensionsY; j > 0; --i) {
maze2[i][j] = lines[i].charAt(j);
System.out.print(maze2[i][j]);
if (i == lines.length) {
System.out.println();
}
}
}
For example:
int dimensionsX = input.nextInt();
int dimensionsY = input.nextInt();
String[] lines = new String[dimensionsY];
char[][] maze2 = new char[dimensionsY][];
for (int j = 0; j < dimensionsY; ++j) {
if (input.hasNextLine()) {
lines[j] = input.nextLine();
if(lines[j].length()<dimensionsX){
System.err.println("we are doomed. Input malformed in line j: it has less then" + dimensionsX + "characters");
System.exit(1);
}
maze2[j] = lines[j].toCharArray();
System.out.println(lines[j]);
//System.out.println(j);
}else{
System.err.println("we are doomed. Input has too few lines");
System.exit(1);
}
}
//taken as is, but makes me wonder if it is intended to have dimensionsX as the Y coordinate but well...
for (int i = dimensionsX; i > 0; --i) {
for (int j = dimensionsY; j > 0; --j) {
System.out.print(maze2[j-1][i-1]);
}
System.out.println();
}
Of course you want to do something different than exiting the program if the input is malformed e.g. throw an exception, or do nothing at all if your input is always correct(well is it?).

LinkedList Matrix, Null Pointer Exception when setting value

I started with a 2D array matrix program that works entirely ok. I converted most of it to implement a linked list version of the same thing. Currently (using .printStackTrace) I find my null pointer exception is from this line -> matrix.setValue(matrixRow, matrixColumn, value);
which calls setValue and the error is thrown at this -> a[x][y] = value; //error in this line
I hope to have included enough code, let me know if more info is helpful. In need of a coding break for the moment. Many thanks.
else { //matrix creation
matrix = new Node();
int matrixRow = 1;
int matrixColumn = 1;
for (int i = 1; i <= matrixSize; i++) {
//scanner one line at a time
scanner = new Scanner(fileIO.getNextLine());
if (scanner.hasNextDouble()) {
while (scanner.hasNextDouble()) {
value = scanner.nextDouble();
matrix.construct(matrixRow, matrixColumn);
matrix.setValue(matrixRow, matrixColumn, value);
matrixColumn++;
}//while
matrixRow++;
matrixColumn = 1;
}//if
}//for
if (matrix.isSquare()) {
determinant = matrixMaths.determinate(matrix);
fileIO.writeToOutput(matrix.toString());
fileIO.writeToOutput("The determinant is: " + String.valueOf(determinant));
fileIO.writeToOutput("\n\n");
} else {
errorMsg = "\n\nMatrix is not square.\n\n";
fileIO.writeToOutput(errorMsg);
}//else
}//else matrix creation
Node construct(int n, int m) {
Node[][] a = new Node[n][m];
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
Node ptr = new Node();
ptr.data = a[i][j];
ptr.right = null;
ptr.down = null;
a[i][j] = ptr;
}
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (j != n - 1)
a[i][j].right = a[i][j + 1];
if (i != n - 1)
a[i][j].down = a[i + 1][j];
}
}
return a[0][0];
}
public void setValue(int x, int y, double value) {
a[x][y] = value; //error in this line
if (x > sizeX) {
sizeX = x;
}
if (y > sizeY) {
sizeY = y;
}
}
* Edit *
I had put in system.out statements right before I called setValue to see that I was passing the values of 1 to the array. The method only gets this far until I get the error.
So, setValue(matrixRow, matrixColumn, value) -> setValue(1,1,value); on the first go through the while loop. I changed to this
int matrixRow = 0;
int matrixColumn = 0;
but then get the new error here (last return in the construct method):
return a[0][0];
another arrayOutOfBounds...
I'm going to try to follow the logic again but not sure yet where to make the fix. Help please!
And changing the row/column = 2 also gets the NUllPtr again.
So, made a few changes and am getting further...
} else { //matrix creation
matrix = new Node();
int matrixRow = 0;
int matrixColumn = 0;
System.out.println("\n" + "matrixSize " + matrixSize);
for (int i = 1; i <= matrixSize; i++) {
//scanner one line at a time
scanner = new Scanner(fileIO.getNextLine());
if (scanner.hasNextDouble()) {
while (scanner.hasNextDouble()) {
value = scanner.nextDouble();
System.out.println(matrixRow + " row number");
System.out.println(matrixColumn + " column number");
System.out.println(value + " value");
matrix.construct(matrixRow, matrixColumn, value);
matrixColumn++;
}//while
matrixRow++;
matrixColumn = 1;
}
My input is this...
3
3 -2 4
-1 5 2
-3 6 4
Output gets through matrices size 1 and 2. It gets as far as the third matrix row 3, column 0. At row 3, col 0, I get the ArrayIndexOutOfBounds error again.
I had it working but then ran into trouble setting the values but.... the project is to be a "matrix as a linked list" which is different than the previous assignment "matrix as a 2D array". So perhaps my structures are incorrect to begin with? Also, My Node class is separate (as an ADT implementing an interface). There is a whole 'nother class for finding the determinant. Not worried about that at right now. Also, we are given the "matrix size" the line before the matrix data in the input. And thank you again!
**Can't sleep edit...
This construct works through the entire input file. So now I just need to figure out where to set the values. (Value is not being assigned here so I'll likely delete it unless I can figure out a way around that).
void construct(int n, int m, double value) {
System.out.println("construct " + n + " n " + m + " m " + value + " value");
Node[][] a = new Node[n + 1][m + 1];
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
Node ptr = new Node();
ptr.data = a[i][j];
ptr.right = null;
ptr.down = null;
a[i][j] = ptr;
a[i][j].right = a[i][j + 1];
a[i][j].down = a[i + 1][j];
}
}
}
It seems to be an off by one error. If we replace the values:
int matrixRow = 1;
int matrixColumn = 1;
into what is being declared, we see that you are accessing the array at the place a[1][1], but your declaration for the array size is Node[][] a = new Node[1][1]; (when replacing n and m by the value above). This means that the only element accessible for setValue is a[0][0] (because arrays have a length of size - 1.
I suggest you do an array bounds-checking if-statement on the setValue function, you'll be able to catch errors like this with greater ease. Another way to check my theory is to set matrixRow and matrixColumn as 2 and insert a debug print statement for the array at the beginning of the setValue function, and see what is the first element populated.
Edit:
The reason you get an error in your construct function is because you are creating a zero length array, and then trying to access its first element (see Why does Java allow arrays of size 0? for more info on zero length arrays in java)
I don't know the nature of your project, but I suggest you separate the logic of your code. It seems that you are representing your matrix as an array of "Node"s, and that you know the size of the matrix beforehand.
If so, I would suggest representing your matrix as a class, and making the construct method return and instance of that class.
At the very least, I see no reason as to why you should need to create the matrix inside the while loop. Create it beforehand, and populate it with values later.

CSV reader perils - Java

I'm trying to read a CSV file and split each line into 4 different integer values via a two-dimensional array in java.
I'm using openCSV 3.8.
For the sake of simplicity, say this is the contents of the CSV file (the full file contains 306 lines just like these):
76,67,0,1
77,65,3,1
78,65,1,2
83,58,2,2
I can read the file just fine, and I can use System.out.println to output each single value to the console, like this:
76
67
0
1
77
65
3
1
78
65
1
2
85
58
2
2
Unfortunately with my code below, designed to enter each value into a separate array element only saves the 4 values in the last line of the file.
And here is my java code (don't mind the size of the iaData array, it's sized for the full CSV file):
public static void main(String[] args) {
//String outputStr = "";
int[][] iaData = new int[306][4];
int i = 0;
int x = 0;
try
{
//Get the CSVReader instance with specifying the delimiter to be used
CSVReader reader = new CSVReader(new FileReader("haberman.data"),',');
String [] nextLine = new String[1250];
//Read one line at a time
while ((nextLine = reader.readNext()) != null)
{
for (i = 0; i <= 305; i++)
{
for (x = 0; x <= 3; x++)
{
iaData[i][x] = Integer.parseInt(nextLine[x]);
}
}
}
for (int z = 0; z <= 3; z++)
{
System.out.println(iaData[0][z] + "\n");
}
reader.close();
}
catch (Exception e) {
e.printStackTrace();
}
}
With this code, I would expect my System.out.println(iaData[0][z] + "\n"); to output the following to the console (the values in the first line of the file):
76
67
0
1
Unfortunately it's not the case, it actually outputs the following (the 4 values in the last line of the file):
83
58
2
2
What is wrong with my code such that iaData[0][0/1/2/3] actually outputs what I would expect to be held in iaData[**3**][0/1/2/3]?
For every line, you start writing with first index i=0.
So for every line you override all information from the line before:
while ((nextLine = reader.readNext()) != null)
{
for (i = 0; i <= 305; i++)
{
for (x = 0; x <= 3; x++)
{
iaData[i][x] = Integer.parseInt(nextLine[x]);
}
}
}
This should solve your problem:
int i = 0;
while ((nextLine = reader.readNext()) != null) {
for (x = 0; x <= 3; x++) {
iaData[i][x] = Integer.parseInt(nextLine[x]);
}
i++;
}
Your current problem is that for each line you are iterating over the entire 2D array, both rowwise and columnwise. This has the effect that only the last row will reflect the currently read line.
Instead, the row counter i should only be incremented after another line has been read from the CSV file. Currently, you are incrementing i for the same line over and over again.
// Read one line at a time
int i = 0;
while ((nextLine = reader.readNext()) != null) {
for (x = 0; x <= 3; x++) {
iaData[i][x] = Integer.parseInt(nextLine[x]);
}
// increment i once, after having processed a single line from the file
++i;
}
There are various things in your code that simply don't make sense.
First, you are init'ing nextLine to probably hold 1250 lines.
String [] nextLine = new String[1250];
But then, you are pushing a single line into that:
while ((nextLine = reader.readNext()) != null)
Either you don't need the first statement; or something is wrong about the second one.
For the actual bug you are observing: it doesn't help that you keep writing the same lines 395 times, too. And that is what your code is doing; because for each line that you read, you do
for (i = 0; i <= 305; i++)
{
for (x = 0; x <= 3; x++)
{
hiaData[i][x] = Integer.parseInt(nextLine[x]);
So you keep overwriting your data, instead of
line1
line2
...
you keep writing
line i
line i...
Thus, in the end, you only got your last line in there.
My recommendation: don't do all that manual size-dependent iterating yourself. Simply use
List<String[]> allLines = csvreader.readAll();
4 values, 395 lines ... that is nothing. Just push all of that into memory with that one call.
Meaning: the library offers you a nice abstraction that requires you one line of code to read all content. You choose to write 20, 30 lines of code instead. And that is the thing: the more code you write, the higher are chances to create bugs.
And finally: do not use such numbers as 305, 4, 1205 directly in your source code. If at all, use constants there. But hard-coding those values in your loops ... very bad practice - you have to change each and any place that deals with your input when for example 5 columns come in, instead of 4.
If the program is going to read the whole file into an array ... is it not enough to read it into memory, and process it later?
Like so:
import au.com.bytecode.opencsv.CSVReader;
import java.io.IOException;
import java.io.StringReader;
import java.util.List;
public class Csv {
public static void main(String[] args) throws IOException {
String string = "76,67,0,1\n" +
"77,65,3,1\n" +
"78,65,1,2\n" +
"83,58,2,2";
CSVReader reader = new CSVReader(new StringReader(string),',');
List<String[]> lines = reader.readAll();
for (String[] entries : lines) {
for (String entry: entries) {
System.out.println(Integer.parseInt(entry));
}
}
}
}
Beware of memory issues and set an upper bound or process a line a time by changing the loop like so:
String[] entries;
while((entries = reader.readNext()) != null) {
for (String entry : entries) {
System.out.println(Integer.parseInt(entry));
}
}
Problems:
1.
for (i = 0; i <= 305; i++)
This cycle is not needed, as reader.readNext() will gather all the lines without the need of further help. So, this is certainly an improvement:
int i = 0;
while ((nextLine = reader.readNext()) != null)
{
//for (i = 0; i <= 305; i++)
//{
for (x = 0; x <= 3; x++)
{
iaData[i++][x] = Integer.parseInt(nextLine[x]);
}
//}
}
2.
The other problem you have is that you iterate only the elements of the first element:
for (int z = 0; z <= 3; z++)
{
System.out.println(iaData[0][z] + "\n");
}
Instead:
for (i = 0; i < iaData.length; i++)
{
for (int z = 0; z <= 3; z++)
{
System.out.println(iaData[i][z] + "\n");
}
System.out.println("");
}

creating 2 dimensional array from text file

I am trying to add values into a 2d array from a text file. I cannot figure out how to convert the input file to teacher's array format. The file contains a first line that goes into an array that represents vertices. That part works fine. Every line after the first line contains numbers for the adjacency matrix. These numbers are read in but for some reason the slots in the matrix are not being filled. I need to use those numbers to fill a double array that would be the same as using this statement:
int[][] edges = {
{0,1}, {0,2},
{1,0},{1,2},
{2,0},{2,1},{2,3},{2,4},{2,6},
{3,2},{3,4},{3,5},
{4,2},{4,3},
{5,3},{5,6},
{6,2},{6,5},{6,7},
{7,6}
I have to read input from a txt file. The names represent the names of the nodes or vertices in my graph. The numbers represent the positions of the vertices in an adjacency matrix. For example the first line represents row o which maps to node john, and it means that john is connected by an edge to node 1 and 2 which are peter and mary. The numbers should map the same way as the array creation above. Here is what the file looks like :
john;peter;mary;susan;george;debbie;tom;bill;
0 1 2
1 0 2
2 0 1 3 4 6
3 2 4 5
4 2 3
5 3 6
6 2 5 7
7 6
And here is my code :
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class TestSocialGraph {
public static void main(String args[]){
String verts;
int[][] edges;
int[] intPasser;
File input = new File("GraphInput.txt");
String[] names;
try {
Scanner reader = new Scanner(input);
verts = reader.next();
names = verts.split(";");
edges = new int[names.length][names.length];
while (reader.hasNextLine()){
int b = 0;
int count = 0;
String passer = reader.nextLine();
// System.out.println(passer);
String[] temp = passer.split(" ");
intPasser = new int[temp.length];
for(int i = 1; i< temp.length; i++){
System.out.println(temp[i]);
intPasser[b] = Integer.parseInt(temp[i]);
b++;
}
System.out.println(intPasser[0]);
for(int i = 0; i< intPasser.length; i++){
edges[count][intPasser[i]] = 1;
}
count++;
}
} catch (FileNotFoundException e) {
System.out.println("File not found. Please place appropriate file and restart program");
System.exit(1);
}
}
}
It looks like you're trying to make an adjacency matrix...
I.e. The first line in your file says
0 1 2
So, this would mean node 0 is connected to node 1 & node 2. It matches with what your teacher has given also:
{0,1}, {0,2},
So, in the final 2D array edges, it should be represented like so (1s in the indexes to which node 0 is connected to):
edges[0] = {0, 1, 1, 0, 0, 0, 0, 0};
Dici's response is absolutely correct in this matter - it's the count variable's location that is creating a problem. Place int count = 0; outside the while loop, and use readLine() instead of read(), and you should get an adjacency matrix representation of that data.
The only problem is that the teacher's representation & the one you're trying to produce here are different. So, consequently, the later logic which processes these inputs will also vary. One program will run with what your teacher has provided, but won't run with the matrices you've created.
---------------------------EDIT---------------------------
In response to the comment, IMO, you'll need to go through the file twice - first to get the number of edges (in this case 20), then to fill your edges array with the actual values.
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class TestSocialGraph {
public static void main(String args[]) {
int[][] edges;
File input = new File("GraphInput.txt");
try {
Scanner reader = new Scanner(input);
reader.nextLine();// Skips the first line (nameList)
int count = 0;
// Count the total number of 2 element arrays
while (reader.hasNextLine()) {
String passer = reader.nextLine();
count += passer.split(" ").length - 1;
}
reader.close();
edges = new int[count][];
int i = 0;
reader = new Scanner(input);
reader.nextLine();// Skips the first line (nameList)
while (reader.hasNextLine()) {
String passer = reader.nextLine();
String[] split = passer.split(" ");
for (int j = 1; j < split.length; j++) {
edges[i + j - 1] = new int[2];
edges[i + j - 1][0] = Integer.parseInt(split[0]);
edges[i + j - 1][1] = Integer.parseInt(split[j]);
}
i += split.length - 1;
}
reader.close();
print(edges);
} catch (FileNotFoundException e) {
System.out.println(e);
}
}
private static void print(int[][] e) {
for (int i = 0; i < e.length; i++) {
for (int j = 0; j < e[i].length; j++)
System.out.print(e[i][j] + " ");
System.out.println();
}
}
}
I hope the code isn't too obscure/unreadable.
There are a lot of things to correct in your code.
verts = reader.next(); should be verts = reader.nextLine();.
in your question edges is a 20 x 2 matrix whereas in your code it is a 8 x 8 square matrix. The number of edges in your file does not seem to depend of the number of names in the first line, so why instantiating the array of edges like this ?
variable b is useless, you can replace it with i in the loop
variable count is never incremented (or at least the incremented value is never used) since it is reinitialized at each turn of the loop. That is the reason why you never fill certain lines.
your two loops could be merged into a unic one, without using a temporary array
Where does you data come from? I would avoid writing/maintaining a parser yourself. This is a waste of time. Did you think about using JSON? Your data (in the Java-code version) looks exactly like that.
When you can turn your data into
{
"vertices" : ["john","peter","mary","susan","george","debbie","tom","bill"],
"edges" : [[0,1], [0,2], ...]
}
you can use a standard JSON parser to read into a document model and directly start using the data.
This is an example of how to work with JSON data:
http://www.mkyong.com/java/json-simple-example-read-and-write-json/

Checking grid for word search game

i made this boggle-type game, and so far it works very well. This method here is for searching the 10x10 grid to see if the word the user entered is correct. The problem i have is that this code only works for words that appear left to right, and top to bottom. Now i don't expect to do diagonal, but i would like to make it to where the words that appear in reverse order are also accepted by the system. I've been told that the word that you enter would have to be flipped (reversed) in order to see if it matches properly (which makes sense. After all, you're looking for a word that is backwords). So exactly how would i achieve this? Now, i'm not very good with coding, so please, if you have time then write down what code i would have to use. Thank you.
public static boolean wordSearch (char[][] table, String search)
{
int ctr = search.length();
String temp = "";
// LEFT TO RIGHT / X-AXIS
for (int row = 0; row < 10; row++) //Checks each row (x) one by one
{
for (int a = 0; a <= (10 - ctr); a++)
{
StringBuilder s = new StringBuilder(10-ctr);//Does... something
for (int x = a; x <= (a+ctr-1); x++) //Checks every possibility in the row
{
s.append(table[row][x]);
temp = s.toString();
if (temp.equals(search))
{
return true;
}
}
}
}
// TOP TO BOTTOM / Y-AXIS
for (int column = 0; column < 10; column++)
{
for (int b = 0; b <= (10 - ctr); b++)
{
StringBuilder v = new StringBuilder(10-ctr);
for (int y = b; y <= (b+ctr-1); y++)//checks every possibility in grid
{
v.append(table[y][column]);
temp = v.toString();
if (temp.equals(search))
{
return true;
}
}
}
}
return false;//if word isn't in grid it returns as false, which then displays an error message
}
EDIT ... the Java version!!! (I have no Java compiler handy right now but I think this is right...)
At the second line of your code, we compute the reverse string;
there are thousands of ways to do this, but this one is pretty self-explanatory (I am assuming there is no white space in your string...):
int ls = search.length(); // length of initial string
StringBuilder sb = new StringBuilder(); // temporary place to store growing string
for(int ii=ls-1;ii>=0; ii--) {
sb.append(search.charAt(ii)); // build the string one character at a time
}
hcraes = sb.toString(); // convert to "regular" string
Now, at every point where you have the line
if (temp.equals(search))
change that line to
if (temp.equals(search) || temp.equals(hcraes))
that should do the trick.

Categories

Resources