Matrix with ArrayList - java

I got this class :
import java.util.*;
public class MatrixArrayList extends AbstractMatrix {
private ArrayList<ArrayList<Integer>> values;
public MatrixArrayList(int nbl, int nbc) {
super(nbl, nbc);
values=new ArrayList<ArrayList<Integer>>();
}
#Override
public int getValue(int x, int y) {
return values.get(x).get(y) ;
}
#Override
public void setValue(int x, int y, int value) {
values.get(x).set(y, value);
}
}
and I got
java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
I want to make a matrix with an ArrayList
i have w problem with this :
valeurs.get(x).set(y, valeur);

It's not clear from your code which call causes the exception, however it is clear that you are not initializing your inner array-list, nor are you adding any objects to it.
When you initialize it in the constructor:
values=new ArrayList<ArrayList<Integer>>();
What you're basically doing is instantiating the values object to be an ArrayList of size 0 (no items have been added to it yet).
Then, if say, you're doing setValue at index 0, you get the exception because when you do get(x), you're basically doing get(0) on a collection of size 0 - there is nothing to get, you exceed the bounds of the your array.
What you might want to do is initialize all arrays in the constructor:
public MatrixArrayList(int nbl, int nbc) {
super(nbl, nbc);
values=new ArrayList<ArrayList<Integer>>(nbl);
for (int i = 0; i < nbl; i++) {
values.add(new ArrayList<Integer>(nbc));
}
}
And then you can access them without a problem in getValue or setValue (you'll get this exception if you actually do exceed the bounds or if you haven't set any value at the specific index yet. See comment below:).
Notice, though, that since you're using the ArrayList object, rather than a primitive int[] array, you still don't have values inside your array. Simply doing new ArrayList<Integer>() or even new ArrayList<Integer>(num) still leaves you with a list of size 0. If you want to cover all your bases, you might want to either initailize your ArrayList, or perform bounds checks before each get you make in either getValue or setValue.

new ArrayList<ArrayList<Integer>>() creates an empty list. To fill that list with values, you need to call add().
Assuming you want to fill matrix with nbl lists of nbc null values:
this.values = new ArrayList<>(nbl);
for (int i = 0; i < nbl; i++) {
ArrayList<Integer> row = new ArrayList<>(nbc);
for (int j = 0; j < nbc; j++)
row.add(null);
this.values.add(row);
}
You could also fill it with 0 values if you want.
Of course, if the matrix cannot change size, it would likely be much better to create a simple array version, instead of the ArrayList version you're trying to create.

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
public class Shell {
static List<ArrayList<ArrayList<Double>>> read(String filename) {
ArrayList<ArrayList<Double>> A = new ArrayList<ArrayList<Double>>();
ArrayList<ArrayList<Double>> B = new ArrayList<ArrayList<Double>>();
String thisLine;
try {
BufferedReader br = new BufferedReader(new FileReader(filename));
// Begin reading A
while ((thisLine = br.readLine()) != null) {
if (thisLine.trim().equals("")) {
break;
} else {
ArrayList<Double> line = new ArrayList<Double>();
String[] lineArray = thisLine.split("\t");
for (String number : lineArray) {
line.add((double) Integer.parseInt(number));
}
A.add(line);
}
}
// Begin reading B
while ((thisLine = br.readLine()) != null) {
ArrayList<Double> line = new ArrayList<Double>();
String[] lineArray = thisLine.split("\t");
for (String number : lineArray) {
line.add((double) Integer.parseInt(number));
}
B.add(line);
}
} catch (IOException e) {
System.err.println("Error: " + e);
}
List<ArrayList<ArrayList<Double>>> res = new LinkedList<ArrayList<ArrayList<Double>>>();
res.add(A);
res.add(B);
return res;
}
static int[][] ijkAlgorithm(ArrayList<ArrayList<Integer>> A,
ArrayList<ArrayList<Integer>> B) {
int n = A.size();
// initialise C
int[][] C = new int[n][n];
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
for (int k = 0; k < n; k++) {
C[i][j] += A.get(i).get(k) * B.get(k).get(j);
}
}
}
return C;
}
static void printMatrix(Matrix matrix, int n) {
for (int i = 0; i < n; i++) {
StringBuilder sb = new StringBuilder(matrix.length);
for (int j = 0; j < n; j++) {
if (j != 0) {
sb.append("\t");
}
String formattedString = String.format("%.0f", matrix.get(i, j))
sb.append(formattedString);
}
System.out.println(sb.toString());
}
}
public static void main(String[] args) {
String filename;
if (args.length < 2) {
filename = "2000.in";
} else {
filename = args[1];
}
List<ArrayList<ArrayList<Double>>> matrices = read(filename);
ArrayList<ArrayList<Double>> A = matrices.get(0);
ArrayList<ArrayList<Double>> B = matrices.get(1);
int n = A.size();
double[][] Aarray = new double[n][n];
double[][] Barray = new double[n][n];
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
Aarray[i][j] = A.get(i).get(j);
Barray[i][j] = B.get(i).get(j);
}
}
Matrix AM = new Matrix(Aarray);
Matrix BM = new Matrix(Aarray);
Matrix CM = AM.times(BM);
printMatrix(CM, n);
}
}
input file that have matrices you want to do this operation
Hope this code helps happy coding.

Related

How to resize a multidimensional array without using an arraylist (java)

I need to reset the size of an array from w[i][j][q][k] to w[i+2][j+2][q][k]. I don't want to use an array of lists as I would have to change large parts of my program.
I read in some threads that it is possible to create a new array of the desired size, and copy the contents from the original array to the new array using java.lang.System.arraycopy(...).
I tried this as follows, but it does not work with my approach:
int [][][][] w = new int [18][18][[Main.V+1][Main.k];
(...)
int[][][][] wNew = new int[20][20][Main.V+1][Main.k];
for(int i=0; i<wNew.length; i++){
for(int j=0; j<wNew[0].length; j++){
for(int q=0; q<wNew[0][0].length; q++){
for(int k=0; k<wNew[0][0][0].length; k++){
System.arraycopy(w, 0, wNew, 0, 18);
}
}
}
}
w = wNew;
(...)
when manipulating the array at the added positions, a java.lang.ArrayIndexOutOfBoundsException: 18 occurs
(example below:
w[0][19][1][0] = 1; (this line now causes an error)
System.arraycopy(w, 0, wNew, 0, 20);
this 20 is the number of array element to copy. You've put the new size, use the old one. In your example it's 18.
Secondly your for loops are based on your new size. This is backward, you have to read your original array and insert into the new array, so you have to iterate on the original array size(for resizing up, of course to make it smaller it would be the other way around).
But more importantly you don't have to iterate on all the dimentions. I'll past you some code you'll can execute to see for yourself.
import java.util.Arrays;
import java.util.Random;
public class Test {
public static final int SIZE_DIM1 = 2;
public static final int SIZE_DIM2 = 2;
public static final int SIZE_DIM3 = 5;
public static final int SIZE_DIM4 = 5;
private static final int INCREMENT = 2;
public static void main(String[] args) {
int[][][][] w = new int[SIZE_DIM1][SIZE_DIM2][SIZE_DIM3][SIZE_DIM4];
randomFill(w);
display(w);
int[][][][] wNew = new int[SIZE_DIM1 + INCREMENT][SIZE_DIM2 + INCREMENT][SIZE_DIM3][SIZE_DIM4];
for (int i = 0; i < w.length; i++) {
for (int j = 0; j < w[i].length; j++) {
System.arraycopy(w[i][j], 0, wNew[i][j], 0, w[i][j].length);
}
}
display(wNew);
w = wNew;
w[0][3][4][4] = 1;
}
public static void randomFill(int[][][][] w) {
Random random = new Random();
for (int[][][] w2 : w) {
for (int[][] w3 : w2) {
for (int[] w4 : w3) {
for (int i = 0; i < w4.length; i++) {
w4[i] = random.nextInt();
}
}
}
}
}
public static void display(int[][][][] w) {
System.out.println("Printing---------------------------------------------------------------------------------");
System.out.print("[\n");
for (int[][][] w2 : w) {
System.out.print("\t[\n");
for (int[][] w3 : w2) {
System.out.print("\t\t[\n");
for (int[] w4 : w3) {
System.out.print("\t\t\t[");
for (int element : w4) {
System.out.print(element + " ");
}
System.out.print("]\n");
}
System.out.print("\t\t]\n");
}
System.out.print("\t]\n");
}
System.out.print("]\n");
}
}
As you can see you don't have to iterate on all the sub arrays. just on the ones that have their sizes changing.
Execute it and it will be obvious.

How do you find the mode of an Array in java?

I'm new to java and I have a homework assignment where I need to find the Mean, median and Mode of an Array. For some reason my code is not putting out the correct answer.
Here is the code I was provided to create the Arrays:
public static void main(String[] args) {
int[] test01 = new int[]{2,2,2,2,2};
int[] test01Results = new int[]{2,2,2,2};
int[] test02 = new int[]{1,2,1,3,5,6,6,1,2,2,2,99,100};
int[] test02Results = new int[]{2,2,17,100};
int[] test03 = new int[]{100,200,300,400,300};
int[] test03Results = new int[]{300,300,260,400};
int[] test04 = new int[]{100};
int[] test04Results = new int[]{100,100,100,100};
int[] test05 = new int[]{100,1};
int[] test05Results = new int[]{1,100,50,100};
Here is what I came up with to try to calculate the Mode:
public int mode() {
int result = 0;
// Add your code here
int repeatAmount = 0; //the amount of repeats accumulating for the current i
int highestRepeat=0; // the highest number of repeats so far
for (int i=0; i<numberArray.length; i++) {
for (int j=i; j<numberArray.length; j++) {
if (i != j && numberArray[i] == numberArray[j]) {
repeatAmount++;
if (repeatAmount>highestRepeat) {
result=numberArray[i];
}
repeatAmount = highestRepeat;
}
repeatAmount=0; // resets repeat Count for next comparison
}
}
return result;
}
I'm getting the correct results for tests 1, 2 and 3 but getting the wrong result for Tests 4 and 5. Does anyone know what I'm doing wrong?
Thanks!
You never assign anything except 0 to highestRepeat. This should work:
public int mode() {
int result = 0;
int highestRepeat=0;
for (int i=0; i<numberArray.length; i++) {
int repeatAmount = 1;
for (int j = i + 1; j < numberArray.length; j++) {
if (numberArray[i] == numberArray[j]) {
repeatAmount++;
if (repeatAmount > highestRepeat) {
result = numberArray[i];
highestRepeat = repeatAmount;
}
}
}
}
return result;
}
Some other improvements:
By starting the inner loop at i+1 you can skip the check if i != j.
By declaring repeatAmount inside the outer loop you can skip
setting it to zero after the inner loop.
If you need some performance, consider using a HashMap for counting the equal array entries.

two quick fix issues - Merge Sort

I have created my version of the merge sort algorithm in java code. My issues are these: when I run the code as is, I get a NullPointerExecpetion in the main on line 27 (see commented line). And I know there is way to make the method calls and instantiate newArray without them being static but Im not quite sure how.. can someone help fix these? I am still relatively new to java so be nice :)
Main:
import java.util.Random;
public class MergeSort_main
{
public static void main(String[] args)
{
int[] originalArray = new int[1000];
Random rand = new Random();
for (int i = 0; i < originalArray.length; i++)
{
int randNum = rand.nextInt(1000)+1;
originalArray[i] = randNum;
}
for(int i = 0; i < originalArray.length; i++)
{
System.out.println(i+"." + originalArray[i]);
}
System.out.println("---------------------End Random Array-------\n");
MergeSortAlgorithm.mergeSortAlg(originalArray);
int[] sortedArray = MergeSortAlgorithm.getSortedArray();
for(int i = 0; i < sortedArray.length; i++) //NULL POINTER EXCEPTION HERE
{
System.out.println(i+ "." + sortedArray[i]);
}
}
}
Algorithm Class:
public class MergeSortAlgorithm
{
private static int[] newArray;
public static void mergeSortAlg(int[] randomNums)
{
int size = randomNums.length;
if (size < 2)
{
return; //if the array can not be split up further, stop attempting to split.
}
int half = size / 2;
int firstHalfNums = half;
int secondHalfNums = size - half;
int[] firstArray = new int[firstHalfNums];
int[] secondArray = new int[secondHalfNums];
for (int i = 0; i < half; i++)
{
firstArray[i] = randomNums[i];
}
for (int i = half; i < size; i++)
{
secondArray[i - half] = randomNums[i];
}
mergeSortAlg(firstArray);
mergeSortAlg(secondArray);
merge(firstArray, secondArray, randomNums);
}
public static void merge(int[] firstArray, int[] secondArray, int[] newArray)
{
int firstHalfNums = firstArray.length;
int secondHalfNums = secondArray.length;
int i = 0; //iterator for firstArray
int j = 0; //iterator for second array
int k = 0; //interator for randomNums array
while (i < firstHalfNums && j < secondHalfNums)
{
if (firstArray[i] <= secondArray[j])
{
newArray[k] = firstArray[i];
i++;
k++;
}
else
{
newArray[k] = secondArray[j];
k++;
j++;
}
}
while (i < firstHalfNums)
{
newArray[k] = firstArray[i];
k++;
i++;
}
while (j < firstHalfNums)
{
newArray[k] = secondArray[j];
k++;
j++;
}
}
public static int[] getSortedArray()
{
return newArray;
}
}
Basically, the only problem with your code is that you don't initialize newArray with any values, resulting in a null.
You are also redefining newArray at the top of your merge function .
The problem is that newArray[] is never instantiated i.e. newArray reference is pointing to null. And, no change is made in the newArray so value or reference returned to main is null. And, then you are performing sortedArray.length where sorted array having a null value.
You have to make newArray[] point to randomNums[].

using a list of lists in java

I'm writing a code that should theoretically take a text file representation of a graph with a number of vertices, edges, and a list of edges, and use depth-first-search to determine if it's bipartite. However I'm using an Arraylist of lists to store the adjacency lists, and I keep getting java.lang.IndexOutOfBoundsException: Index: 1, Size: 0 error at the for loop in the childColor method
import java.io.File;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.*;
import static java.lang.System.*;
import java.util.*;
public class detect_bipartite {
public static void main(String[] args){
int bipartCheck = 1;
List<Integer> numList = new ArrayList<Integer>();
File inFile = null;
//separate white space
if (0 < args.length) {
inFile = new File(args[0]);
}
BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader(inFile));
String text = null;
while ((text = reader.readLine()) != null) {
String[] tmp = text.split(" ");
for(String str: tmp)
if(!str.equals("")){
numList.add(Integer.parseInt(str));}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (reader != null) {
reader.close();
}
} catch (IOException e) {
}
}
int n = numList.get(0);
int m = numList.get(1);
List<Integer> edgeA = new ArrayList<Integer>();
List<Integer> edgeB = new ArrayList<Integer>();
for(int i=2; i<numList.size(); i++){
if(i%2==0){edgeA.add(numList.get(i));}
else if(i%2==1){edgeB.add(numList.get(i));}
}
List<List<Integer>> adjLists = new ArrayList<List<Integer>>(n);
for(int j = 1; j <= adjLists.size(); j++){ //get adjacency lists
for(int a=1; a <=edgeA.size(); a++){
if(edgeA.get(a)==j){ (adjLists.get(j)).add(edgeB.get(a));}
if(edgeB.get(a)==j){ (adjLists.get(j)).add(edgeA.get(a));}
}
}
int[] color = new int[n];
Arrays.fill(color, 0);
//0 = uncolored
//1 = red
//2 = blue
int bipart = childColor(n, 1, adjLists, color, 1);
if (bipart==0){bipartCheck = 0;}
for(int d = 0; d < n; d++) //for any disconnected graphs
{
if(color[d] == 0){
bipart = childColor(n, d, adjLists, color, 1);}
if (bipart==0){bipartCheck = 0;}
}
if(bipartCheck == 1){
System.out.println("Bipartite");
} else{
System.out.println("Not a Bipartite");
}
}
public static int childColor(int n, int node, List<List<Integer>> adjLists, int[] color, int nodeColor){
if(color[node] == nodeColor){
return 1;}
int bipart = 1;
int newColor;
if(nodeColor == 1){newColor = 2;}
else{newColor = 1;}
if(color[node] == newColor)
{return 0;}
color[node] = nodeColor;
for(int k = 0; k < adjLists.get(node).size(); k++){ **//This is the error line**
bipart = childColor(n, adjLists.get(node).get(k), adjLists, color, newColor);
if(bipart == 0)
{return 0;}
}
return bipart;
}
}
When you do:
List<List<Integer>> adjLists = new ArrayList<List<Integer>>(n);
You create an ArrayList with initial capacity n. This does not mean the list has size n though. In fact, since the list has no elements, its size is 0. Given that, 1 <= 0 is false and this loop is never executed:
for(int j = 1; j <= adjLists.size(); j++){ //get adjacency lists
for(int a=1; a <=edgeA.size(); a++){
if(edgeA.get(a)==j){ (adjLists.get(j)).add(edgeB.get(a));}
if(edgeB.get(a)==j){ (adjLists.get(j)).add(edgeA.get(a));}
}
}
So, when you call childColor(n, 1, adjLists, color, 1), adjLists is empty. When you try to access an element at index 1, by doing adjLists.get(node), there is no element, thus the IndexOutOfBoundsException.
Also note that Java lists and arrays indices start at 0, not 1.
To solve the problem, you could initialize all the lists before trying to use them:
List<List<Integer>> adjLists = new ArrayList<List<Integer>>(n);
for (int i = 0; i < n; i++) {
adjLists.add(new ArrayList<>());
}

MergeSort Implementation IndexOutOfBounds Java

import java.util.ArrayList;
import java.util.Random;
public class Merge {
private static ArrayList<Integer> newArrayList;
public static ArrayList<Integer> generateArray(int n){
newArrayList = new ArrayList<Integer>(n);
Random rand = new Random();
for (int i = 0; i<n; i++){
newArrayList.add(rand.nextInt(n + 1));
}
return newArrayList;
}
public static ArrayList<Integer> mergeSort(ArrayList<Integer> x){
if (x.size()>1){
ArrayList<Integer> ArrayList1 = new ArrayList<Integer>(x.size()/2);
ArrayList<Integer> ArrayList2 = new ArrayList<Integer>(x.size()-(x.size()/2));
for (int i = 0; i<newArrayList.size()/2; i++){
ArrayList1.set(i, newArrayList.get(i));
}
for (int i = (newArrayList.size()/2); i<((newArrayList.size()/2)+(newArrayList.size()-newArrayList.size()/2)); i++){
ArrayList2.set(i-(newArrayList.size()/2), newArrayList.get(i));
}
//ArrayList1 = mergeSort(ArrayList1);
//ArrayList2 = mergeSort(ArrayList2);
int j = 0;
int k = 0;
int a = 0;
while(ArrayList1.size() != j && ArrayList2.size() != k){
if (ArrayList1.get(j) < ArrayList2.get(k)){
x.set(a, ArrayList1.get(j));
a++;
j++;
} else {
x.set(a, ArrayList2.get(k));
a++;
k++;
}
}
while (ArrayList1.size()!=j){
x.set(a, ArrayList1.get(j));
a++;
j++;
}
while (ArrayList2.size()!=k){
x.set(a, ArrayList2.get(k));
a++;
k++;
}
}
return x;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
ArrayList<Integer> new1;
//ArrayList<Integer> new2;
//ArrayList<Integer> new3;
new1 = generateArray(10);
//new2 = generateArray(100);
//new3 = generateArray(1000);
System.out.println(new1);
mergeSort(new1);
System.out.println(new1);
}
}
I am attempting to implement a mergeSort method but I keep getting the following error:
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
at java.util.ArrayList.RangeCheck(ArrayList.java:547)
at java.util.ArrayList.set(ArrayList.java:337)
at Merge.mergeSort(Merge.java:23)
at Merge.main(Merge.java:73)
Any ideas?
You are attempting to set a position that doesn't exist yet in your ArrayList called ArrayList1. You've set the initial capacity to x.size() / 2, but there's nothing in it yet.
It looks like you are attempting to set each position, starting with position 0, so just add the elements instead. Replace
for (int i = 0; i<newArrayList.size()/2; i++){
ArrayList1.set(i, newArrayList.get(i));
}
with
for (int i = 0; i<newArrayList.size()/2; i++){
ArrayList1.add(newArrayList.get(i));
}
And you'll need to make similar changes to the for loop after that, which populates ArrayList2.

Categories