Adding jagged arrays beginner - java

I'm a beginner at java at struggling with this:
I am trying to sum two jagged arrays ( n and m, both double [][]) of the same size (each is length 3 at the first level, then of length x-1,x and x-1 respectively at the second level).
The problem I'm having is to specify the length that each array within the jagged array should be, at the moment my code is producing an n x n array because I've specified the length as n[1] rather than as a parameter, but if I try and use sum[i].length=n[i].length I get the error, "cannot assign value to final variable". So I know this part is wrong but I don't know what is right...
Thanks for the help!
My code:
else if (isValidTridiagonal(m)== true && isValidTridiagonal (n) == true)
{
int size = n[1].length; /** specifying all lengths to be x where they shouldnt be*/
sum = new double[3][size];
for (int i = 0; i < n.length; i++)
{
for(int j = 0; j< n[i].length; j++)
{
sum [i][j]= n[i][j] + m [i][j];
}
}
return sum;
}

There is some missing information. As far as I can tell there are two things you need to fix. You seem to have "sum" as a final variable already defined in your code.
Secondly, you are declaring a new array that is 3xsize big. If you want a jagged array in that sence, you must leave one of the brackets empty and in the first loop insert a new array of the wanted size.
double[][] sum = new double[3][]; //Make sure this is unique within the scope
for(int i = 0; i < 3; i++) { //if you want dynamic scaling you'll need to replace 3 in the array as well.
int size = n[i].length; //size of the new row
sum[i] = new double[size]; // Inserting a new array of the wanted size
for(int j = 0; j< sum[i].length; j++)
{
sum[i][j]= n[i][j] + m[i][j];
}
}
return sum;

The problem is probably with this line:
sum = new double[3][size];
Here you create an incorrect, non-jagged array of size [3][2]
When you try to set sum[1][2] (2nd, 3rd index), you will not be able to.
Otherwise, the code looks correct and I got a sum to work using this:
public static void main(String[] args) {
int[][] n = new int[3][];
n[0] = new int[2];
n[0][0] = 1;
n[1] = new int[3];
n[2] = new int[2];
int[][] m = new int[3][];
m[0] = new int[2];
m[1] = new int[3];
m[1][2] = 1;
m[2] = new int[2];
int[][] sum = new int[3][];
sum[0] = new int[2];
sum[1] = new int[3];
sum[2] = new int[2];
for (int i = 0; i < n.length; i++) { // n.length will be 3
for (int j = 0; j < n[i].length; j++) { // n[i].length will be 2, 3 and 2
sum[i][j] = n[i][j] + m[i][j];
}
}
System.out.println("Sum: ");
for (int i = 0; i < sum.length; i++) {
for (int j = 0; j < sum[i].length; j++) {
System.out.print(sum[i][j] + "|");
}
System.out.println();
}
}
This will print off:
Sum:
1|0|
0|0|1|
0|0|

Related

Java pascal triangle initialization question

I have this code below as I saw from textbook
public static int[][] Pascal(int N) {
int[][] result = new int[N][]; // Build a grid with specific number of rolls
for (int i = 0; i < N; i += 1) {
result[i] = new int[i + 1]; // Build an empty row with length
result[i][0] = result[i][i] = 1;
for (int j = 1; j < i; j += 1) {
result[i][j] = result[i - 1][j - 1] + result[i - 1][j];
}
}
return result;
}
I have no question for how this Pascal triangle is achieved, all very clear.
However, I did learned before that to create an Array, length must be given,
for example, int[] A = int[]; will give me Error
It has to be int[] A = int[N]; or int[] A = int[]{1,2,3,etc.};
So when we create the array grid int[][] result = new int[N][];
How is it allow me to only specify the number of rows, but leave the length of each row with blank?
I did noticed that the length of each roll was defined later at result[i] = new int[i + 1];, I still don't understand why this grid is allowed to be initiated.
Thanks!

How do I read through a 2D array without searching out of bounds?

I have a 2D array acting as a grid.
int grid[][] = new int[5][5];
How do I search through the grid sequentially as in (0,0), (1,0), (2,0), (3,0), (4,0) then (0,1), (1,1), (2,1) ... without getting any array out of bounds exceptions.
I'm new to programming and I just can't get my head around how to do this.
You know your lengths, now use a for loop to circle through the array.
for (int i = 0;i<5;i++){
for (int j = 0;i<5;i++){
int myInt = grid[i][j];
//do something with my int
}
}
To get the lengths at runtime you could do
int lengthX = grid.length; //length of first array
int lengthY = 0;
if ( lengthX>0){ //this avoids an IndexOutOFBoundsException if you don't know if the array is already initialized yet.
lengthY = grid[0].length; //length of "nested" array
}
and then do the for loop with lengthX and lengthY.
You will need two nested loop in order to access the two dimensions of your array:
int grid[][] = new int[5][5];
for(int i = 0; i < 5; i++ ) {
for(int j = 0; j < 5; j++ ) {
int value = grid[i][j];
}
}
Use 2 forloops like the following example:
for(int i = 0; i < 5; i++){
for(int j = 0; j < 5; j++){
System.out.println(grid[i][j]);
}
}
Also i would suggest that when initializing an array to write it like this:
int[][] grid = new int[5][5]; // note the double brackets are after int and not grid
Try this:
for(int i=0;i<5;i++)
{
for(int j=0;j<5;j++)
{
System.out.println(grid[j][i]);
}
}
This code (like the other answers) uses two for loops.
It does however add some handling of edge-cases
static int[] find(int[][] mtx, int valueToLookFor)
{
int rows = mtx.length;
if(rows == 0)
return new int[]{-1,-1};
int cols = mtx[0].length;
if(cols == 0)
return new int[]{-1, -1};
for(int r=0;r<rows;r++)
{
for(int c=0;c<cols;c++)
{
if(mtx[r][c] == valueToLookFor)
return new int[]{r,c};
}
}
return new int[]{-1,-1};
}

After counting sort the result array has one more element (0) than the original one

So I have a problem, this method is supposed to sort an array of integers by using counting sort. The problem is that the resulting array has one extra element, zero. If the original array had a zero element (or several) it's fine, but if the original array didn't have any zero elements the result starts from zero anyway.
e.g. int input[] = { 2, 1, 4 }; result -> Sorted Array : [0, 1, 2, 4]
Why would this be happening?
public class CauntingSort {
public static int max(int[] A)
{
int maxValue = A[0];
for(int i = 0; i < A.length; i++)
if(maxValue < A[i])
maxValue = A[i];
return maxValue;
}
public static int[] createCountersArray(int[] A)
{
int maxValue = max(A) + 1;
int[] Result = new int[A.length + 1];
int[] Count = new int[maxValue];
for (int i = 0; i < A.length; i++) {
int x = Count[A[i]];
x++;
Count[A[i]] = x;
}
for (int i = 1; i < Count.length; i++) {
Count[i] = Count[i] + Count[i - 1];
}
for (int i = A.length -1; i >= 0; i--) {
int x = Count[A[i]];
Result[x] = A[i];
x--;
Count[A[i]] = x;
}
return Result;
}
}
You are using int[] Result = new int[A.length + 1]; which makes the array one position larger. But if you avoid it, you'll have an IndexOutOfBounds exception because you're supposed to do x-- before using x to access the array, so your code should change to something like:
public static int[] createCountersArray(int[] A)
{
int maxValue = max(A) + 1;
int[] Result = new int[A.length];
int[] Count = new int[maxValue];
for (int i = 0; i < A.length; i++) {
int x = Count[A[i]];
x++;
Count[A[i]] = x;
}
for (int i = 1; i < Count.length; i++) {
Count[i] = Count[i] + Count[i - 1];
}
for (int i = A.length -1; i >= 0; i--) {
int x = Count[A[i]];
x--;
Result[x] = A[i];
Count[A[i]] = x;
}
return Result;
}
Here you go: tio.run
int maxValue = max(A) + 1;
Returns the highest value of A + 1, so your new array with new int[maxValue] will be of size = 5;
The array Result is of the lenght A.lenght + 1, that is 4 + 1 = 5;
The first 0 is a predefinied value of int if it is a ? extends Object it would be null.
The leading 0 in your result is the initial value assigned to that element when the array is instantiated. That initial value is never modified because your loop that fills the result writes only to elements that correspond to a positive number of cumulative counts.
For example, consider sorting a one-element array. The Count for that element will be 1, so you will write the element's value at index 1 of the result array, leaving index 0 untouched.
Basically, then, this is an off-by-one error. You could fix it by changing
Result[x] = A[i];
to
Result[x - 1] = A[i];
HOWEVER, part of the problem here is that the buggy part of the routine is difficult to follow or analyze (for a human). No doubt it is comparatively efficient; nevertheless, fast, broken code is not better than slow, working code. Here's an alternative that is easier to reason about:
int nextResult = 0;
for (int i = 0; i < Count.length; i++) {
for (int j = 0; j < Count[i]; j++) {
Result[nextResult] = i;
nextResult++;
}
}
Of course, you'll also want to avoid declaring the Result array larger than array A.

Build an array from existing arrays?

int[] StarTime = new int[20];
int[] duration = new int[40];
int[] EndTime = new int[StarTime.length];
StarTime[0] = 0;
ExponentialDistribution exp = new ExponentialDistribution(4.0);
for(int j = 1; j < 20; j++){
StarTime[j] = (int)exp.sample() + 1+StarTime[j-1];
}
for(int k = 0; k < 20;k ++){
duration[k] = 20 + (int)(Math.random() * ((120 - 10) + 1));
}
I have two arrays StarTime and duration. I want to build an array whose each index is assigned the value which is sum of the values of the indexes of these two arrays. Like suppose EndTime is the array I want to create and if StarTime[0] is 2 and duration[0] is 4 and EndTime[0] should be 6.
How should I do this?
There is no reason for giving type mismatch, while you are adding two int array into another int array. It should work:
for(int k = 0; k < 20; k++){
EndTime[k] = StarTime[k] + duration[k];
}
Ensure that exp.sample() is really casting into int. Also ensure the arrays are of same type.

MultiDimensional ArrayList in kmeans clustering algorithm

I am trying to implement kmeans algorithm for a certain Music Recommendation System in Java.
I have generated 2 arrays,playsFinal[](the total play-count of an artist by all users in the dataset) and artFinal[] (the unique artists in the entire dataset) . The playcount of every artFinal[i] is playsFinal[i]. For k,I have chosen kclusters=Math.sqrt(playsFinal.length)/2.
I have an array clusters[kclusters][playsFinal.length] and the first position clusters[i][0] for every 0<i<kclusters is filled with a certain value,which is basically the initial mean as in kmeans algorithm.
int j = 0;
for (int i = 0; i < n && j < kclusters; i += kclusters) {
clusters[j][0] = weighty[j];//initial means
System.out.println(clusters[j][0]);
j++;
}
Here,weight[] is a certain score given to every artist.
Now,in the following function I am returning the index,ie,which cluster the plays[i] should be added to.
public static int smallestdistance(double a, double[][] clusters) {
a = (double) a;
double smallest = 0;
double d[] = new double[kclusters];
for (int i = 0; i < kclusters; i++) {
d[i] = a - clusters[i][0];
}
int index = -1;
double d1 = Double.POSITIVE_INFINITY;
for (int i = 0; i < d.length; i++)
if (d[i] < d1) {
d1 = d[i];
index = i;
}
return index;
}
If not obvious,I am finding the minimum distance between playsFinal[i] and the initial element in every clusters[j][0] and the one that is the smallest,I am returning its index (kfound). Now at the index of the clusters[kfound][] I want to add the playsFinal[i] but here is where I am stuck. I can't use .add() function like in ArrayList. And I guess using an ArrayList would be way better. I have gone through most of the articles on ArrayList but found nothing that could help me. How can I implement this using a multidimensional ArrayList?
Thanks in advance.
My code is put together as follows:
int j = 0;
for (int i = 0; i < n && j < kclusters; i += kclusters) {
clusters[j][0] = weighty[j];//initial means
System.out.println(clusters[j][0]);
j++;
}
double[] weighty = new double[artFinal.length];
for (int i = 0; i < artFinal.length; i++) {
weighty[i] = (playsFinal[i] * 10000 / playsFinal.length);
}
n = playsFinal.length;
kclusters = (int) (Math.sqrt(n) / 2);
double[][] clusters = new double[kclusters][playsFinal.length];
int j = 0;
for (int i = 0; i < n && j < kclusters; i += kclusters) {
clusters[j][0] = weighty[j];//initial means
System.out.println(clusters[j][0]);
j++;
}
int kfound;
for (int i = 0; i < playsFinal.length; i++) {
kfound = smallestdistance(playsFinal[i], clusters);
//HERE IS WHERE I AM STUCK. I want to add playsFinal[i] to the corresponding clusters[kfound][]
}
}
public static int smallestdistance(double a, double[][] clusters) {
a = (double) a;
double smallest = 0;
double d[] = new double[kclusters];
for (int i = 0; i < kclusters; i++) {
d[i] = a - clusters[i][0];
}
int index = -1;
double d1 = Double.POSITIVE_INFINITY;
for (int i = 0; i < d.length; i++)
if (d[i] < d1) {
d1 = d[i];
index = i;
}
return index;
}
Java's "multidimensional arrays" are really just arrays whose elements are themselves (references to) arrays. The ArrayList equivalent is to create a list containing other lists:
List<List<Foo>> l = new ArrayList<>(); //create outer ArrayList
for (int i = 0; i < 10; i++) //create 10 inner ArrayLists
l.add(new ArrayList<Foo>());
l.get(5).add(foo1); //add an element to the sixth inner list
l.get(5).set(0, foo2); //set that element to a different value
Unlike arrays, the lists are created empty (as any list), rather than with some specified number of slots; if you want to treat them as drop-in replacements for multidimensional arrays, you have to fill them in manually. This implies your inner lists can have different lengths. (You can actually get "ragged" multidimensional arrays by only specifying the outer dimension (int[][] x = new int[10][];), then manually initializing the slots (for (int i = 0; i < x.length; ++i) x[i] = new int[i]; for a "triangular" array), but the special syntax for multidimensional array creation strongly predisposes most programmers to thinking in terms of "rectangular" arrays only.)

Categories

Resources