I have String array like this one:
String[][][][][] map = new String[9][13][2][1][1];
and when I'm trying update one fild, like this:
map[0][0][1][0][1] = "true";
every fild is updating to "true", this one:
map[0][1][1][0][1]
this one:
map[0][2][1][0][1]
why this is happening?
this is my code:
int UP = 0;
int UP_RIGHT = 1;
int RIGHT = 2;
int DOWN_RIGHT = 3;
int DOWN = 4;
int DOWN_LEFT = 5;
int LEFT = 6;
int LEFT_UP = 7;
String[][][][][] map = new String[9][13][2][1][1];
public PitchMoveHelper() {
String[][] move = {
{String.valueOf(UP), "false"},
{String.valueOf(UP_RIGHT), "false"},
{String.valueOf(RIGHT), "false"},
{String.valueOf(DOWN_RIGHT), "false"},
{String.valueOf(DOWN), "false"},
{String.valueOf(DOWN_LEFT), "false"},
{String.valueOf(LEFT), "false"},
{String.valueOf(LEFT_UP), "false"}
};
String[][] used = {{"used", "false"}};
for(int z = 0; z < 9; z++) {
for(int x = 0; x < 13; x++) {
map[z][x][0] = used;
map[z][x][1] = move;
}
}
//this.updateLeftBand();
//this.updateRightBand();
//this.updateTopBand();
//this.updateBottomBand();
map[0][0][1][0][1] = "true";
System.out.println(Arrays.deepToString(getPitchMap()));
}
Your immediate problem is that the String array stores references, not actual strings. When you say
map[z][x][0] = used;
map[z][x][1] = move;
There is a single instance of used being referenced by ALL elements [z][x][0] of map (and the same for move and [z][x][1]. Any change indexed by the 4th of 5th subscript is changing that single instance, affecting what is seen by all subscripts.
To clarify more, all the following entries in map point to the same instance:
map[0][0][0]
map[0][1][0]
.
.
map[0][12][0]
map[1][0][0]
etc.
To solve the problem you need to make a deep copy of used and move for every assignment in the loop:
for(int z = 0; z < 9; z++) {
for(int x = 0; x < 13; x++) {
map[z][x][0] = deepCopy(used);
map[z][x][1] = deepCopy(move);
}
}
Where deepCopy() makes a complete copy of the input array.
String[][] deepCopy(String [][] arr)
{
String[][] temp = new String[arr.length][];
for (int i=0; i<arr.length; i++)
{
temp[i] = new String[arr[i].length];
for (int j=0; j<arr[i].length; j++)
temp[i][j] = arr[i][j];
}
return temp;
}
The key thing you need to realize is that
int[][] example = new int[2][2];
example[1][0] = 1;
example[0] = example[1];
Does NOT COPY the second row to the first. But it makes it an ALIAS to the same memory - i.e. the row is identical to the first.
If you want to copy an array, element-per-element, use
System.arraycopy(...);
If you want to do copy an array-of-arrays, you need a deep copy.
The simplest thing for you is if you copy every single entry. This may be somewhat slower, but it is probably a concept you can easily use for now.
Again:
array2 = array1;
DOES NOT COPY array1 to array2. But it makes them one array.
Related
I'm trying to check whether an array of arrays has any duplicate values. The end goal would be an if statement saying:
if (arr does NOT have duplicate values) {continue code}
int [][] arr = new int[3][2];
int [] x = new int[1];
arr[0][0] = 1;
arr[0][1] = 1;
arr[1][0] = 1;
arr[1][1] = 2;
arr[2][0] = 1;
arr[2][1] = 2;
x = arr.getUnique(); /I assume it'll use getUnique() but I can't even get that to work
Any help would be awesome! Thanks
Java has a HashSet you can use to have a collection without duplicates.
Find a way to convert your array into a HashSet and compare the number of their elements. If they have the same number of elements, each element in your array is unique, if the HashSet is smaller, it means some duplicates have been removed.
You could create a helper function of your own like this:
private static boolean arrayHasDuplicates(int[][] arr) {
for (int i = 0; i < arr.length; i++)
{
for (int y = 0; y < arr.length; y++)
{
if (arr[i].length != arr[y].length) continue;
if (i == y) continue;
boolean same = true;
for (int x = 0; x < arr[y].length; x++)
{
if (arr[i][x] != arr[y][x]) {
same = false;
break;
}
}
if (same) return same;
}
}
return false;
}
I'm trying to implement a method that uses multiple String[] arrays to print a wordlist which contains every possible combination of the Strings in the arrays, in order and using max. 1 String of each array.
example: {"this" | "that"} {"is" | "was"} {"cool" | "lame"}
String[] array1 = {"this", "that"};
String[] array2 = {"is", "was"};
String[] array3 = {"cool", "lame"};
should be used for the following output:
thisiscool
thatiscool
thiswascool
thatwascool
thiswaslame
thatwaslame
thisislame
thatislame
I've been experimenting with nested for-loops:
String out1 = "";
for(int a = 0; a < array1.length; a++) {
out1 = array1[a];
System.out.println(out1);
for(int b = 0; b < array2.length; b++) {
out1 += array2[b];
System.out.println(out1);
for(int c = 0; c < array3.length; c++) {
out1 += array3[c];
System.out.println(out1);
This didn't work well though. Maybe there's a better approach to this?
String[] array1 = {"this", "that"};
String[] array2 = {"is", "was"};
String[] array3 = {"cool", "lame"};
String text="";
for(int a = 0; a < array1.length; a++) {
text=array1[a];
for(int b = 0; b < array2.length; b++) {
text+=array2[b];
for(int c = 0; c < array3.length; c++){
System.out.println(text+array3[c]);
}
text=array1[a];
}
}
Demonstration of same logic in JS
Run the following snippet
let array1 = ["this", "that"];
let array2 = ["is", "was"];
let array3 = ["cool", "lame"];
let text="";
for(let a = 0; a < array1.length; a++) {
text=array1[a];
for(let b = 0; b < array2.length; b++) {
text+=array2[b];
for(let c = 0; c < array3.length; c++){
console.log(text+array3[c]);
}
text=array1[a]
}
}
.as-console-wrapper { max-height: 100% !important; top: 0; }
#Supercool. has already left a perfect answer.
But as your opinion, I've been trying to figure out if there's a better way to visualize than nested for-loops, and I've come up with a way to "recursive call"
By using a 'double array' and 'recursive',
although you add a new array, you don't have to write an additional for-loop.
Like this
public class StackOver
{
static String[][] array = {{"this","that"},
{"is","was"},
{"cool","lame"},};
public static void recString(String[][] a, int index, String output) {
//make break-point
if(index == a.length) { //if 'index' reached to the end of array 'a'?
System.out.println(output); //print out string 'output' that collected so far
//output should be = (a[0][?] + a[1][?] +...+ a[length-1][?])
return; //And end the method.
}
// if 'index' didn't reach to the end of array ::
//If there's an array that hasn't been explored yet,
for(int i = 0; i < a[index].length; i++) {
recString(a, index+1, output + a[index][i]);
//Add 1 to 'index' and add String out put that added '[index][i]'
//as parameters and call this method again.
//This form is called recursive call!
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
String t = "";
recString(array,0,t);
}
}
Even if the array changes, with recursive calls,
you can examine every array without changing the code and draw possible combinations.
Ex).
static String[][] array = {{"I","You","They"},
{"love","hate"},
{"me","you"},
{"too","either"},};
Well, the grammar is a little awkward, but it's an example of stretching the arrangement a little bit longer.
Full disclosure; I needed to know this for an assignment. I wanted to return a single array to a multidimensional array from a method. I circumvented the issue with the below code by returning it to another 1-dimensional array then using a for loop to transfer values.
public class test
{
public static void main ( String args[] )
{
int[][] array1 = new int [100][5];
int[] temp = new int [5];
int num = 0;
temp = setValue();
for (int i = 0; i<=4; i++) // cycle 1
{
array1[num][i]= temp[i];
}
System.out.format("\n\n");
}
public static int[] setValue()
{
int[] array3 = new int [5];
for (int i = 0; i<=4; i++)
{
array3[i]= 2;
}
return array3;
}
}
Is there a more conventional way to return array3 to array1 without cycle 1? Something along the lines of
array1[num][] = setValue();
Comments:
The method returns a new array, so no need to initialize temp, or better yet, initialize it to return value:
int[] temp = setValue();
Java doesn't have 2D arrays, just arrays of arrays, so the entire inner array can be replaced, instead of copying values:
for (int i = 0; i <= 4; i++) // cycle 1
{
array1[num] = temp;
}
When you do that, you shouldn't allocate the inner arrays, i.e. replace [5] with []:
int[][] array1 = new int[100][];
Now there is actually no need for temp anymore, leaving main as just:
int[][] array1 = new int[100][];
int num = 0;
array1[num] = setValue();
Since you probably want to fill the entire 2D array:
int[][] array1 = new int[100][];
for (int num = 0; num < array1.length; num++) {
array1[num] = setValue();
}
As #VinceEmigh hinted above you can simply do array1[num] = setValue();
see
int arr[][] = new int[5][];
for (int x = 0; x < arr.length; x++) {
arr[x] = setValue();
}
for (int x = 0; x < arr.length; x++) {
for (int y = 0; y < arr[x].length; y++) {
System.out.println(arr[x][y]);
}
}
I am attempting to solve a semi-difficult problem in which I am attempting to create an array and return a 3 dimensional array based on the parameter which happens to be a 2 dimensional int array. The array I'm attempting to return is a String array of 3 dimensions. So here is the code:
public class Displaydata {
static String[][][] makeArray(int[][] dimensions) {
String myArray[][][];
for (int i = 0; i < dimensions.length; i++) {
for (int j = 0; j < dimensions[i].length; j++) {
myArray[][][] = new String[i][j][]; //getting error here.
}
}
return myArray;
}
static void printArray(String[][][] a) {
for (int i = 0; i < a.length; i++) {
System.out.println("\nrow_" + i);
for (int j = 0; j < a[i].length; j++) {
System.out.print( "\t");
for (int k = 0; k < a[i][j].length; k++)
System.out.print(a[i][j][k] + " ");
System.out.println();
}
}
}
public static void main(String[] args) {
int [][] dim = new int[5][];
dim[0] = new int[2];
dim[1] = new int[4];
dim[2] = new int[1];
dim[3] = new int[7];
dim[4] = new int[13];
dim[0][0] = 4;
dim[0][1] = 8;
dim[1][0] = 5;
dim[1][1] = 6;
dim[1][2] = 2;
dim[1][3] = 7;
dim[2][0] = 11;
for (int i = 0; i < dim[3].length;i++)
dim[3][i] = 2*i+1;
for (int i = 0; i < dim[4].length;i++)
dim[4][i] = 26- 2*i;
String[][][] threeDee = makeArray(dim);
printArray(threeDee);
}
}
As you can see from the source code, I'm getting an error when I try to create an instance of my 3-dimensional array which I'm attempting to return. I'm supposed to create a three dimensional array with the number of top-level rows determined by the length of dimensions and, for each top-level row i, the number of second-level rows is determined by the length of dimensions[i]. The number of columns in second-level row j of top-level row i is determined by the value of dimensions[i][j]. The value of each array element is the concatenation of its top-level row index with its second-level row index with its column index, where indices are represented by letters : ‘A’ for 0, ‘B’ for 1 etc. (Of course, this will only be true if the indices don’t exceed 25.) I don't necessarily know where I'm going wrong. Thanks!
You should not be initializing the array on every iteration of the loop. Initialize it once outside the loop and then populate it inside the loop.
static String[][][] makeArray(int[][] dimensions) {
String[][][] myArray = new String[25][25][1];
for (int i = 0; i < dimensions.length; i++) {
for (int j = 0; j < dimensions[i].length; j++) {
myArray[i][j][0] = i + "," + j;
}
}
return myArray;
}
I just plugged in values for the size of the first two dimensions, you will need to calculate them based on what you put in there. The 'i' value will always be dimensions.length but the 'j' value will be the largest value returned from dimensions[0].length -> dimensions[n-1].length where 'n' is the number of elements in the second dimension.
Also you will need to set up a way to convert the numbers in 'i' and 'j' to letters, maybe use a Map.
I guess you should initialize the array as
myArray = new String[i][j][]; //getting error here.
I think
myArray[][][] = new String[i][j][]; //getting error here.
should be:
myArray[i][j] = new String[5]; // I have no idea how big you want to go.
And then you can fill in each element of you inner-most array like such:
myArray[i][j][0] = "first item";
myArray[i][j][1] = "second string";
...
I think you should just change that line to:
myArray = new String[i][j][]; //look ma! no compiler error
Also, you would need to initialize myArray to something sensible (perhaps null?)
I need a method that given input 2D array {{1,2},{3,4}} and (int)row=2; (int)column = 3, will produce a concatenated 2D array {{1,2,1,2,1,2}{3,4,3,4,3,4}}.
My attempt was to use a nested for loop to expand them both horizontally and and vertically, but was unsuccessful. This is what I have so far:
int row = 2;
int column = 5;
int count = 0;
int[][] list = {{12,3},{3,4}};
int [][] renewed = new int[row*list.length][column*list[0].length];
for (int l = 0; l<list.length; l++) {
for (int k = 0; k<renewed.length; k+= list.length) {
renewed[l+k] = list[l];
}
}
System.out.println(Arrays.deepToString(renewed));
}
}
^This produces list[][] expanded vertically, for the first column
int row = 2;
int column = 4;
int[][] list = {{12,3},{3,4}};
int [][] renewed = new int[row*list.length][column*list[0].length];
for (int i = 0; i<list[0].length; i++) {
for (int j = 0; j<renewed[0].length; j+=list[0].length) {
renewed[0][j+i] = list[0][i];
}
}
System.out.println(Arrays.toString(renewed[0]));
}
^This produces list[][] expanded horizontally, for the first row;
So how can I concatenate these two methods in order to produce a method that expands BOTH horizontally and vertically?
I think the easiest way is to iterate over every position in the new array and use the remainder operator % to get the right entry of the original.
int[][] list = {{1,2},{3,4}};
int row = 2;
int column = 5;
int [][] renewed = new int[row*list.length][column*list[0].length];
for (int i = 0; i < renewed.length; i++) {
for (int j = 0; j < renewed[0].length; j++) {
renewed[i][j] = list[i % list.length][j % list[0].length];
}
}
System.out.println(Arrays.deepToString(renewed));