I have the following array: [1,2,3,4,5,6,7,8,9]
And I have to return based on a group and step parameters the following values
E.g.:
group = 3; step = 3;
[
[1,2,3],
[4,5,6],
[7,8,9],
[1,2,3]
]
group = 3; step = 2;
[
[1,2,3],
[3,4,5],
[5,6,7],
[7,8,9],
[9,1,2],
[2,3,4],
[4,5,6],
[6,7,8],
[8,9,1],
[1,2,3]
]
group = 3; step = 4;
[
[1,2,3],
[5,6,7],
[9,1,2],
[4,5,6],
[8,9,1],
[3,4,5],
[7,8,9],
[2,3,4],
[6,7,8],
[1,2,3]
]
So far I have this code snippet (in Java):
public static String[][] arrayOfArrays(String[] arr, int step, int group) {
int size = (arr.length / step) 1;
String[][] list = new String[size][group];
int start = 0;
for (int i = 0; i < size; i ) {
for(int j = 0; j < group; j ) {
list[i][j] = arr[start];
start ;
}
if(start == arr.length) {
start = 0;
}
}
return list;
}
I am new to algorithms and I want to understand how should I start thinking in order to solve the problem?
Thank you
CodePudding user response:
I would say the first thing you have to figure out is how large is the resulting list that you want to return going to be. From what I can tell from your examples above, you keep adding lists of size group until the first row matches the last row. Once we know the size, then we can accurately create an array with appropriate sizes to stuff our data into, then return it.
public static int[][] arrayOfArrays(int[] arr, int step, int group) {
int size = 0; // Keeps track of how many rows we got
int c = 1;
// Figure out the size by counting by offset till we come back to starting with 1
// Each time we count a full list add how many rows it would take
// to add that full list. Once we get back to starting with 1
// Just add that final row
while(true)
{
// Move number counter by how many indexes we will have moved in a list length
c = step*(arr.length/group);
// Because it wraps, lets do a modulo operation by the length of the array
c %= arr.length;
// Lets add how many rows we would have created this loop
size = arr.length/group;
if(c == 1) // Are we back to one as a first element in the row
{
size =1; // Add one more for that final row
break;
}
}
// Now that we know size, lets make our array
int[][] list = new int[size][group];
// Stuff the array with data until we are done
c = 1; // Reset our counter to 1
for(int r = 0; r < size; r )
{
for(int g = 0; g < group; g )
{
list[r][g] = c;
c = (c%arr.length) 1; // Index and loop through the list
}
}
return list;
}
CodePudding user response:
Not much experience here either, but I'll try and help as it seems really interesting. I used your code and changed the returned array to an array of ints to match your example.
Edit: Thanks to the answer of @RoyceIrving I understood the logic behind how many inner-arrays are there. I now believe my solution answer your needs.
Take a look:
public static int[][] arrayOfArrays(int[] arr, int step, int group) {
int size = (arr.length % step == 0) ? step 1 : arr.length 1;
int[][] list = new int[size][group];
for (int i = 0; i < size; i ) {
int stepper = (step*i) % arr.length;
for(int j = 0; j < group; j ) {
list[i][j] = arr[stepper];
stepper ;
if (stepper == arr.length) {
stepper = 0;
}
}
}
return list;
}
Note the major changes:
- size depends wether the given array (arr) divides by given step (step). If it does, size equals to step 1. Otherwise, it equals to the array length (arr.length) 1.
- The variable "stepper" serves as a correct starting point for each inner array(in accordance to given "step"). This variable is used to add the correct number to the array and is reset to 0 when reaching the array's length. A modulo was added to prevent over-sizing it as well.