For this intro-level assignment, I have to set up a 2D multidimensional array from a file and from a double[][]
a and apply several methods to them. For now, I'm mostly concerned with simply initializing the arrays. I'm trying to figure out a way to take a test file, read the first int as the number of rows, the first integer of each line as the number of columns per row, and each double as a member of the array.
public class MDArray
{
static int rowCount;
static int columnCount;
private static double[][] mdarray = new double[rowCount][columnCount];
public MDArray(double[][] a)
{
mdarray = a;
}
public MDArray(String file)
{
Scanner input = null;
try
{
input = new Scanner(new FileInputStream("ragged.txt"));
}
catch (FileNotFoundException e)
{
System.out.println("File Not Found.");
System.exit(0);
}
while(input.hasNextDouble())
{
rowCount = input.nextInt();
for(int i = 0; i < rowCount; i++)
{
columnCount = input.nextInt();
for(int j = 0; j < columnCount; j++)
{
double value = input.nextDouble();
mdarray[i][j] = value;
}
}
}
}
public static boolean isRagged()
{
for(int i = 0; i < mdarray.length; i++)
{
int rowLength1 = mdarray.length;
for(int j = i + 1; j < mdarray.length; j++)
{
int rowLength2 = mdarray.length;
if(rowLength1 != rowLength2)
{
return true;
}
}
}
return false;
}
public static int getNumberOfRows()
{
int numRows = 0;
for(int i = 0; i < mdarray.length; i++)
{
numRows++;
}
return numRows;
}
public static int getNumberOfCols()
{
int numCols = 0;
for(int i = 0, j = i + 1; i < mdarray.length; i++)
{
for(int k = 0; k < mdarray[i].length; k++)
{
if(mdarray[i].length > mdarray[j].length)
{
numCols++;
}
}
}
return numCols;
}
public static double getValAt(int i, int j)
{
if(i > mdarray.length || j > mdarray[i].length)
{
double invalid = Double.NaN;
return invalid;
}
double valAt = mdarray[i][j];
return valAt;
}
public static void sort(boolean byColumn)
{
if(isRagged() == true)
{
System.out.println("Ragged arrays cannot be sorted by column.");
}
else{
for(int i = 0; i < mdarray.length; i++)
{
for(int j = 0; j < mdarray[i].length; j++)
{
for(int k = j + 1; k < mdarray[i].length; k++)
{
if(mdarray[i][j] < mdarray[i][k])
{
double temp = mdarray[i][j];
mdarray[i][k] = mdarray[i][j];
mdarray[i][j] = temp;
}
}
}
}
}
}
public static int hamming(boolean byColumn)
{
int hamVal = 0;
if(isRagged() == true)
{
System.out.println("Ragged arrays cannot be sorted by column.");
}
else{
for(int i = 0; i < mdarray.length; i++)
{
for(int j = 0; j < mdarray[i].length; j++)
{
for(int k = j + 1; k < mdarray[i].length; k++)
{
if(mdarray[i][j] < mdarray[i][k])
{
double temp = mdarray[i][j];
mdarray[i][k] = mdarray[i][j];
mdarray[i][j] = temp;
hamVal++;
}
}
}
}
}
return hamVal;
}
public static double[] max()
{
double[] maxVal = new double[mdarray.length];
for(int i = 0, j = i + 1; i < maxVal.length; i++)
{
for(int k = 0; k < mdarray[i].length; k++)
{
if(mdarray[i][k] > mdarray[j][k])
{
maxVal = mdarray[i];
}
}
}
return maxVal;
}
public String toString()
{
String arrayString = "";
for(int i = 0; i < mdarray.length; i++)
{
for(int j = 0; j < mdarray[i].length; j++)
{
arrayString += ", " + mdarray[i][j];
}
arrayString = arrayString + "/n";
}
return arrayString;
}
}
This was the file I was testing the MDArray(String file) with:
3
2 4.1 8.9
5 9.5 2.0 7.3 2.1 8.9
3 1.3 5.2 3.4
I think the problem is that the rowCount
and columnCount
integers are not initialized, but I'm not sure how to initialize them to a variable length with basic array skills. This is also affecting the other constructor as well. Being an intro-level course, I am not supposed to use more advanced techniques such as ArrayList
. In addition, I can't verify if the methods are correct, since I don't have an array to test them with.
EDIT: While I did implement many of the suggestions in the answers, such as changing everything to non-static and other changes, I'm still getting a NullPointerException
for the line mdarray[i][j] = input.nextDouble();.
I assume it has to do with the private double[][] mdarray
, which is required in the assignment specifications. Now I'm trying to find a way to initialize it such that it can be overridden in the later methods.
You have to initialize the array in your constructor, since that's when you know the dimensions :
public MDArray(String file)
{
Scanner input = null;
try {
input = new Scanner(new FileInputStream("ragged.txt"));
}
catch (FileNotFoundException e) {
System.out.println("File Not Found.");
System.exit(0);
}
rowCount = input.nextInt();
mdarray = new double[rowCount][]; // init the array
for(int i = 0; i < rowCount; i++) {
columnCount = input.nextInt();
mdarray[i] = new double[columnCount]; // init the current row
for(int j = 0; j < columnCount; j++) {
mdarray[i][j] = input.nextDouble();
}
}
}
You could initialize your arrays by putting the amount of rows and columns on the first 2 lines of your multidimensional array, if i had 10 rows and 12 columns i could do something like this:
public void arrayStuff() {
File fileToRead = new File("YOUR LINK HERE");
String[][] data;
try (BufferedReader reader = new BufferedReader(new FileReader(fileToRead))) {
String line;
data = new String[Integer.parseInt(reader.readLine())][Integer.parseInt(reader.readLine())];
while((line = reader.readLine()) != null) {
// read the rest here..
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
I am using an AutoCloseable (which is why the try is between these ()'s, but this is so that i don't have to close it afterwards.
Basically, first i read the amount of rows there are and then the amount of columns there are, so if i had this file:
10
12
a b c d e f g h i j
a b c d e f g h i j
a b c d e f g h i j
a b c d e f g h i j
a b c d e f g h i j
a b c d e f g h i j
a b c d e f g h i j
a b c d e f g h i j
a b c d e f g h i j
a b c d e f g h i j
a b c d e f g h i j
a b c d e f g h i j
It'd be able to read all of this, because the amount of rows and columns were defined in the file.
You don't use the fields rowCount and columnCount: you can remove them
The mdarray field should be non-static, so should be the methods that use them (if it was a utility class, you wouldn't have any constructor)
The arrays can be created while reading the file:
Scanner input = null;
try
{
input = new Scanner(new FileInputStream("ragged.txt"));
}
catch (FileNotFoundException e)
{
System.out.println("File Not Found.");
System.exit(0);
}
int rowCount = input.nextInt();
mdarray = new double[rowCount][];
for(int i = 0; i < rowCount; i++)
{
int columnCount = input.nextInt();
mdarray[i] = new double[columnCount];
for(int j = 0; j < columnCount; j++)
{
double value = input.nextDouble();
mdarray[i][j] = value;
}
}
methods getNumberOfRows() and getNumberOfCols() count be much simpler:
public int getNumberOfRows()
{
return mdarray.length;
}
public int getNumberOfCols() {
int result = 0;
for (double[] col: mdarray) {
if (col.length > result) {
result = col.length;
}
}
return result;
}
In getValueAt(), the test is wrong; it should be:
if(i >= mdarray.length || j >= mdarray[i].length)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.