I'm working with a 2D array and what I'm trying to do in the below method is swap two values. The 'currentBoard' variable is a 2D array that needs should not be edited. The 'cpy' variable a duplicate of the 'currentBoard' and needs its variables to be changed. 'nbt' and 'bt' are 1D arrays that used to point to an index in the 2D array. The code for the function 'copyBoard' is always below if it helps
The issue I'm having is that at on the line marked with ** when the value in the 'cpy' array is changed for some reason the value in 'currentBoard' is being changed as well. I really can't figure out why this is happening....
private void Swap(int[] nbt, int[] bt, ArrayList<State> children, String direction) {
int[][] cpy = copyBoard(currentBoard);
int temp = cpy[nbt[0]][nbt[1]];
**cpy[nbt[0]][nbt[1]] = currentBoard[bt[0]][bt[1]];
cpy[bt[0]][bt[1]] = temp;
children.add(new Board(cpy, this.getGOAL(), this.getRows(), this.getColumns(), (this.getDirections() + direction + ", ")));
}
In case it helps here is the values that are assigned to the variables at the point when the code is on the line marked with **
nbt = {1, 0}
bt = {0, 0}
private int[][] copyBoard(int[][] state)
{
int[][] returnArray = new int[rows][columns];
for (int i = 0, j = 0; i*j < PUZZLE_SIZE; i++, j++)
{
returnArray[i] = state[i];
}
return returnArray;
}
A 2D array is an array of references to arrays. So if you assign returnArray[i] = state[i], you are simply making returnArray[i] refer to the same array that state[i] refers to. Thus, modifying returnArray[i][j] will modify the j'th element of whatever state[i] was. You have to create a deep copy of the "rows", too, e.g.:
private int[][] copyBoard(int[][] state)
{
int[][] returnArray = new int[rows][columns];
for (int i = 0, j = 0; i*j < PUZZLE_SIZE; i++, j++)
{
// deep copy of row:
returnArray[i] = Arrays.copyOf(state[i], state[i].length);
}
return returnArray;
}
Check out this short write-up on 2D arrays, it should give you a better idea of what's going on here. In particular, this little image, which represents int nums[][] = new int[5][4] (although it makes more sense in context):
By the way, your loop logic looks a little odd to me; even if the math happens to work out in your situation, it is a bit clearer to do this instead:
for (int i = 0; i < rows; i++)
Or more generally:
for (int i = 0; i < returnArray.length; i++)
These, of course, assume that state.length == rows; but you get the idea.
Related
I just began studying java. One of the tasks was to create a function to create a reverse 2-dimensional array, for example, if the input array was {1,2}{3,4}, the new array must be {4,3}{2,1}. The code below is the method I created. The problem is that the old array d is affected by the loop along with c, so, in this case, it copies half of the values into c, but also replaces the last half of d, so the second half of c is just a mirrored first half, basically, in the example case both c and d will be like this in the end: {4,3}{3,4}. I checked c==d and c.equals(d) after cloning, both show false.
Also, I tried using Arrays.copy, the result was the same. Plus I want the method to work on the arrays that can have their sub-arrays with different lengths, for example, {1,2}{3}{4,5}, and I don't know if it'll work on such arrays.
static int[][] reversematrix(int[][] d) {
int[][] c = d.clone();
for (int i = d.length-1, x = 0; i >= 0; x++, i--) {
for (int j = d[i].length-1, y = 0; j>=0; y++, j--) {
c[x][y] = d[i][j];
}
}
return c;
Can you tell me how to make d(imput array) unaffected by the method/loop? I think the problem is in copying, so I'd love to know a proper way of copying a 2D array into a new object, but if it is in something else, please tell me waht it is.
UPD: Thanks to #sascha the solution was found. Here's the code if someone is interested:
static int[][] reversematrix(int[][] d) {
int[][] c = new int[d.length][];
for (int i = d.length-1, x = 0; i >= 0; x++, i--) {
c[x] = new int[d[i].length];
for (int j = d[i].length-1, y = 0; j>=0; y++, j--) {
c[x][y] = d[i][j];
}
}
return c;
}
I have a problem converting from arraylist to a 2d array.
in this code the return value is the reference not value
public int[][] convertTO2D(java.util.List<ArrayList<Integer>> arrayList){
int listSize = arrayList.size();
int[][] darr = new int[listSize][];
for(int i = 0; i < listSize; i++) {
ArrayList<Integer> sublist = arrayList.get(i);
int sublistSize = sublist.size();
darr[i] = new int[sublistSize];
for(int j = 0; j < sublistSize; j++) {
darr[i][j] = sublist.get(j);
}
// System.out.println("");
}
return darr;
}
and the this is the output of return
[[I#5b273190, [I#740ac748, [I#314e4266, [I#1ea46732, [I#7ced7ec7, [I#5effd695]
how can I fix that ??
How do you print a 2d array?
use this one System.out.println(Arrays.deepToString(array));
Whenever you see something like [I#5b273190 coming from a println() statement, it usually means that you are printing a reference to an object, not the contents of the object.
In this instance, you can either iterate through each of your nested arrays printing the values separately (if you want to perform custom formatting), or you can use the method suggested by #vagueness:
System.out.println(Arrays.deepToString(array));
I'm trying to make an encryption program where the user enters a message and then converts the "letters into numbers".
For example the user enters a ABCD as his message. The converted number would be 1 2 3 4 and the numbers are stored into a one dimensional integer array. What I want to do is be able to put it into a 2x2 matrix with the use of two dimensional arrays.
Here's a snippet of my code:
int data[] = new int[] {10,20,30,40};
*for(i=0;i<2;i++)
{
for(j=0;j<2;j++)
{
for (int ctr=0; ictr<data.length(); ictr++){
a[i][j] = data[ctr];}
}
}
I know there's something wrong with the code but I am really lost.
How do I output it as the following?
10 20
30 40
(instead of just 10,20,30,40)
Here's one way of doing it. It's not the only way. Basically, for each cell in the output, you calculate the corresponding index of the initial array, then do the assignment.
int data[] = new int[] {10, 20, 30, 40, 50, 60};
int width = 3;
int height = 2;
int[][] result = new int[height][width];
for(int i = 0; i < height; i++) {
for(int j = 0; j < width; j++) {
result[i][j] = data[i * width + j];
}
}
Seems like you want to output a 2xn matrix while still having the values stored in a one-dimensional array. If that's the case then you can to this:
Assume the cardinality m of your set of values is known. Then, since you want it to be 2 rows, you calculate n=ceil(m/2), which will be the column count for your 2xn matrix. Note that if m is odd then you will only have n-1 values in your second row.
Then, for your array data (one-dimension array) which stores the values, just do
for(i=0;i<2;i++) // For each row
{
for(j=0;j<n;j++) // For each column,
// where index is baseline+j in the original one-dim array
{
System.out.print(data[i*n+j]);
}
}
But make sure you check the very last value for an odd cardinality set. Also you may want to do Integer.toString() to print the values.
Your code is close but not quite right. Specifically, your innermost loop (the one with ctr) doesn't accomplish much: it really just repeatedly sets the current a[i][j] to every value in the 1-D array, ultimately ending up with the last value in the array in every cell. Your main problem is confusion around how to work ctr into those loops.
There are two general approaches for what you are trying to do here. The general assumption I am making is that you want to pack an array of length L into an M x N 2-D array, where M x N = L exactly.
The first approach is to iterate through the 2D array, pulling the appropriate value from the 1-D array. For example (I'm using M and N for sizes below):
for (int i = 0, ctr = 0; i < M; ++ i) {
for (int j = 0; j < N; ++ j, ++ ctr) {
a[i][j] = data[ctr];
}
} // The final value of ctr would be L, since L = M * N.
Here, we use i and j as the 2-D indices, and start ctr at 0 and just increment it as we go to step through the 1-D array. This approach has another variation, which is to calculate the source index explicitly rather than using an increment, for example:
for (int i = 0; i < M; ++ i) {
for (int j = 0; j < N; ++ j) {
int ctr = i * N + j;
a[i][j] = data[ctr];
}
}
The second approach is to instead iterate through the 1-D array, and calculate the destination position in the 2-D array. Modulo and integer division can help with that:
for (int ctr = 0; ctr < L; ++ ctr) {
int i = ctr / N;
int j = ctr % N;
a[i][j] = data[ctr];
}
All of these approaches work. Some may be more convenient than others depending on your situation. Note that the two explicitly calculated approaches can be more convenient if you have to do other transformations at the same time, e.g. the last approach above would make it very easy to, say, flip your 2-D matrix horizontally.
check this solution, it works for any length of data
public class ArrayTest
{
public static void main(String[] args)
{
int data[] = new int[] {10,20,30,40,50};
int length,limit1,limit2;
length=data.length;
if(length%2==0)
{
limit1=data.length/2;
limit2=2;
}
else
{
limit1=data.length/2+1;
limit2=2;
}
int data2[][] = new int[limit1][limit2];
int ctr=0;
//stores data in 2d array
for(int i=0;i<limit1;i++)
{
for(int j=0;j<limit2;j++)
{
if(ctr<length)
{
data2[i][j] = data[ctr];
ctr++;
}
else
{
break;
}
}
}
ctr=0;
//prints data from 2d array
for(int i=0;i<limit1;i++)
{
for(int j=0;j<limit2;j++)
{
if(ctr<length)
{
System.out.println(data2[i][j]);
ctr++;
}
else
{
break;
}
}
}
}
}
I've initialized a 1d and 2d array and now I basically just want to be able to perform matrix multiplication on them. However, I'm not quite getting the proper answer. I think I've mixed up the for loop where I try to ensure I only multiply the correct values, but can't quite get the hang of it.
edit: I've fixed it, I was misunderstanding what the length method of a 2D array returned (thought it returned columns and not rows). The below code is my corrected code. Thanks everyone.
public static double[] getOutputArray(double[] array1D, double[][] array2D) {
int oneDLength = array1D.length;
int twoDLength = array2D[0].length;
double[] newArray = new double[array2D[0].length]; // create the array that will contain the result of the array multiplication
for (int i = 0; i < twoDLength; i++) { // use nested loops to multiply the two arrays together
double c = 0;
for (int j = 0; j < oneDLength; j++) {
double l = array1D[j];
double m = array2D[j][i];
c += l * m; // sum the products of each set of elements
}
newArray[i] = c;
}
return newArray; // pass newArray to the main method
} // end of getOutputArray method
There are some problems, first of all, you should decide how the vectors represented, are you multiplying from left or right.
For the maths: vector 1xn times matrix nxm will result in 1xm, while matrix mxn times nx1 result in mx1.
I think the following would work for you:
public static double[] getOutputArray(double[] array1D, double[][] array2D) {
int oneDLength = array1D.length;
int twoDLength = array2D.length;
double[] newArray = new double[twoDLength]; // create the array that will contain the result of the array multiplication
assert twoDLength >0 && array2D[0].length == oneDLength;
for (int i = 0; i < twoDLength; i++) { // use nested loops to multiply the two arrays together
double c = 0;
for (int j = 0; j < oneDLength; j++) {
double l = array1D[j];
double m = array2D[i][j];
c += l * m; // sum the products of each set of elements
}
newArray[i] = c;
}
return newArray; // pass newArray to the main method
} // end of getOutputArray method
I hope I did not make a mistake, while trying to fix.
A project I am doing requires me to find horizontal and vertical sums in 2 dimensional arrays. So pretty much its a word search (not using diagonals) but instead of finding words, the program looks for adjacent numbers that add up to int sumToFind. The code below is what I have come up with so far to find horizontal sums, and we are supposed to implement a public static int[][] verticalSums as well. Since I have not yet completed the program I was wondering, first of all, if what I have will work and, secondly, how the array verticalSums will differ from the code below. Thank you
public static int[][] horizontalSums(int[][] a, int sumToFind) {
int i;
int start;
int sum = 0;
int copy;
int [][] b = new int [a[0].length] [a.length];
for (int row = 0; row < a.length; row++) {
for ( start = 0; start < a.length; start++) {
i = start;
sum = i;
do {
i++;
sum = sum + a[row][start];
}
while (sum < sumToFind);
if(sum == sumToFind) {
for (copy = start; copy <= i; copy++) {
b[copy] = a[copy];
}
}
for (i = 0; i < a[0].length; i++) {
if (b[row][i] != a[row][i])
b[row][i] = 0;
}
}
}
return b;
}
Your code won't work.... (and your question is "if what I have will work?" so this is your answer).
You declare the int[][] b array as new int [a[0].length] [a.length] but I think you mean: new int [a.length] [a[0].length] because you base the row variable off a.length, and later use a[row][i].
So, if your array is 'rectangular' rather than square, you will have index-out-of-bounds problems on your b array.
Your comments are non-existent, and that makes your question/code hard to read.
Also, you have the following problems:
you set sum = i where i = start and start is the index in the array, not the array value. So, your sum will never be right because you are summing the index, not the array value.
in the do..while loop you increment i++ but you keep using sum = sum + a[row][start] so you just keep adding the value to itself, not the 'next' value.
At this point it is obvious that your code is horribly broken.
You need to get friendly with someone who can show you how the debugger works, and you can step through your problems in a more contained way.
Test is very simple
public static void main(String[] args) {
int[][] a = {{1, 2}, {1, 0}};
int[][] result = Stos.horizontalSums(a, 1);
System.out.println(Arrays.deepToString(result));
}
Result
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 2
When you fix this problem, then this should print something like this
[[1, 2], [1, 0]]