I have little problem with removing col from a 2d array.
The goal is to remove from every row specific index "2" and give it back.
Its how it need to be
I made it but got little problem with 0 at the end.
Its how I got
private static void removeEntry(int[][] workArray, int col) {
int row = workArray.length;
//largest row count
int max = 0;
int tempNum = 0;
for (int[] ints : workArray) {
tempNum = 0;
for (int j = 0; j < ints.length; j++) {
tempNum++;
if (tempNum > max) {
max = tempNum;
}
}
}
int [][] newArray = new int[row][max];
for(int i = 0; i < row; i++) {
for(int j = 0; j < max; j++) {
if(j < col && j < workArray[i].length) {
newArray[i][j] = workArray[i][j];
}else if (j == col) {
// Do nothing
} else if (j > col && j < workArray[i].length) {
newArray[i][j - 1] = workArray[i][j];
}
}
}
for (int i = 0; i < workArray.length; i++) {
for (int j = 0; j < workArray[i].length; j++) {
workArray[i][j] = newArray[i][j];
}
}
Then I tried to remove 0 but don't work
int remIndex = 0;
for (int i = 0; i < workArray.length; i++) {
for (int j = remIndex; j < workArray[i].length-1; j++) {
if(workArray[i][j] == remIndex){
workArray[i][j] = workArray[i][j + 1];
}
}
}
An array is a container of data that occupies a contiguous block of memory, its size should be defined when the array is being instantiated and can't be changed.
If you need an array of smaller or greater length, then you need to create a new one and copy all previously added elements that should be retained.
There's also no such thing in Java as "2D" arrays, we can create a nested array, i.e. an array containing other arrays.
And similarly to how we can reassign an integer value at a particular index in a plain array int[], we can change a reference in the array of arrays, i.e. we can make it point to another (newly created) array.
And that's what is required according to do in your assignment since the method is void. I.e. the given array needs to be changed by replacing all of its "rows", that greater or equal in length than the given column to remove col, with a new array that will retain all the previous element except for the one at index col.
private static void removeEntry(int[][] workArray, int col) {
for (int row = 0; row < workArray.length; row++) {
if (workArray[row].length <= col) { // no need to change anything
continue;
}
int newLength = workArray[row].length - 1;
int[] newRow = new int[newLength]; // creating a new row shorter by 1
for (int oldCol = 0, newCol = 0; oldCol < workArray[row].length; oldCol++, newCol++) {
if (oldCol == col) { // skipping the target column
newCol--; // newCol would be incremented automatically at the end of the iteration, but we want it to remain the same
continue;
}
newRow[newCol] = workArray[row][oldCol];
}
workArray[row] = newRow; // reassigning the row
}
}
main()
public static void main(String[] args) {
int[][] testArr =
{{1, 2},
{1, 2, 3},
{1, 2, 3, 4}};
removeEntry(testArr, 2);
// printing the testArr
for (int[] arr: testArr) {
System.out.println(Arrays.toString(arr));
}
}
Output:
[1, 2]
[1, 2]
[1, 2, 4]
A link to the Online Demo
If you've made the method to be void by mistake, you are required to return a new array, i.e. the return type int[] (check the requirements of your assignment carefully). Then a minor change needs to be applied to the logic explained and implemented above: every array should be replaced with a new one and then placed into the newly created resulting array.
Note Arrays.copyOf() allows creating a duplicate of the hole array, and System.arraycopy() can help you to copy the elements in the given range from one array into another, but because you are working on an assignment I suggest you to do it manually with loops because you are expected to demonstrate the knowledge on how to manipulate with arrays, not the knowledge of special utility features (unless otherwise specified in the assignment).
private static int[][] removeEntry(int[][] workArray, int col) {
int[][] result = new int[workArray.length][];
for (int row = 0; row < workArray.length; row++) {
int newLength = col < workArray[row].length ? workArray[row].length - 1 : workArray[row].length;
int[] newRow = new int[newLength];
for (int oldCol = 0, newCol = 0; oldCol < workArray[row].length; oldCol++, newCol++) {
if (oldCol == col) {
newCol--;
continue;
}
newRow[newCol] = workArray[row][oldCol];
}
result[row] = newRow; // reassigning the row
}
return result;
}
main()
public static void main(String[] args) {
int[][] testArr =
{{1, 2},
{1, 2, 3},
{1, 2, 3, 4}};
int[][] newArr = removeEntry(testArr, 2);
// printing the testArr
for (int[] arr: newArr) {
System.out.println(Arrays.toString(arr));
}
}
Output:
[1, 2]
[1, 2]
[1, 2, 4]
A link to the Online Demo
Here is my approach on this. I used System.arraycopy() to copy the array up to the removed column and from directly after the removed column to the end. This way, we remove the column completely from the array.
private static int[][] removeEntry(int[][] workArray, int col) {
int[][] resultArray = new int[workArray.length][];
int index = 0;
for (int[] row : workArray) {
if (row.length - 1 < col) {
resultArray[index] = row;
index++;
continue;
}
int[] arrayCopy = new int[row.length - 1];
System.arraycopy(row, 0, arrayCopy, 0, col);
System.arraycopy(row, col + 1, arrayCopy, col, row.length - col - 1);
resultArray[index] = arrayCopy;
index++;
}
return resultArray;
}
Arrays are of fixed size. At the time of initializing array, a default value is stored in it. Here, 0 is stored as default. So I would suggest you to not initialize "col" as "max" but rather do it in for loop like this :-
int [][] newArray = new int[row][];
for(int i = 0; i < row; i++) {
if(col <= workArray[i].length){
newArray[i] = new int[workArray[i].length-1]; //initialize it here
}
for(int j = 0; j < workArray[i].length; j++) {
if(j < col) {
newArray[i][j] = workArray[i][j];
}else if (j == col) {
// Do nothing
} else if (j > col) {
newArray[i][j - 1] = workArray[i][j];
}
}
}
return newArray;
You are also supposed to return modified array as we can't changed the size of array and thus we had to create a new one ( newArray ). So do change the method definition as :-
private static int[][] removeEntry(int[][] workArray, int col)
Finally, whole method would look like :-
private static int[][] removeEntry(int[][] workArray, int col) {
int row = workArray.length;
//largest row count
int [][] newArray = new int[row][];
for(int i = 0; i < row; i++) {
if(col <= workArray[i].length){
newArray[i] = new int[workArray[i].length-1]; //initialize it here
}
for(int j = 0; j < workArray[i].length; j++) {
if(j < col) {
newArray[i][j] = workArray[i][j];
}else if (j == col) {
// Do nothing
} else if (j > col) {
newArray[i][j - 1] = workArray[i][j];
}
}
}
return newArray;
}
and you can use it like :-
workArray = removeEntry(workArray, 2);
Related
I have an assignment in which I have to create the following classes:
public class Square3x3 {
private int[][] mat = new int [3][3];
public boolean allThere(){
int[] options = {1,2,3,4,5,6,7,8,9};
for (int i = 0 ; i < NUM_OF_ROWS; i++){
for(int j =0 ; j < NUM_OF_COLS; j++){
for (int k = 0; k < options.length; k++){
if(mat[i][j] == options[k]) {
options[k] = -1;
break;
}
}
}
}
for (int num : options) {
if(num != -1) return false;
}
return true;
}
a class that represents a 3x3 2d array, and a sudoku class that is constructed by a 3x3 2d array of Square3x3 objects:
public class Sudoku {
private Square3x3[][] grid9x9 = new Square3x3[3][3];
}
I need to check if the 9x9 grid is valid, I have a method to check if a single 3x3 object is valid, but I also need to check if the entire row/col of the 9x9 grid is valid (has all the numbers from 1-9)
Here's one way to improve your data definitions using the same two classes. Define one 9 x 9 int array, and pass a sub-array to your allThere method by using the row and column indexes.
public class Sudoku {
private int[][] grid9x9 = new int[9][9];
}
public class Square3x3 {
public boolean allThere(int[][] grid, int row, int column) {
int[] options = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
for (int i = row; i < row + 3; i++) {
for (int j = column; j < column + 3; j++) {
options = testOptions(options, grid[i][j]);
}
}
for (int num : options) {
if (num != -1)
return false;
}
return true;
}
private int[] testOptions(int[] options, int gridValue) {
for (int i = 0; i < options.length; i++) {
if (gridValue == options[i]) {
options[i] = -1;
break;
}
}
return options;
}
}
I cleaned up your allThere code to document that the break statement only breaks out of the options loop.
Basically I have a function that receives a two dimensional array, adds an extra row and then calculates the sum of the columns and stores the results for each individual column in the extra row that was created earlier. Here is my code:
public static int[][] sum(int[][] array) {
int tempArray[][] = new int[array.length + 1][array[0].length];
for (int column = 0; column < tempArray[0].length; column++) {
int total = 0;
for (int row = 0; row < tempArray.length; row++) {
total += tempArray[row][column];
}
tempArray[tempArray.length][column] = total;
}
return tempArray;
}
So when I run a for loop to print the results I get an ArrayIndexOutOfBounds error for some reason that refers to the function. I think my logic is correct but I can't seem to make it work. For some more context the values for the array are entered by the user. Thank you whoever will answer !
You are getting ArrayIndexOutOfBounds because you are accessing the index more than the bound of array in the below line:
tempArray[tempArray.length][column] = total;
Replace it with following the line would solve your problem:
tempArray[tempArray.length - 1][column] = total;
However your code still won't work as your summation logic have bug. You are calculating the total by the following line.
total += tempArray[row][column];
But your tempArray doesn't have any value but zeros. To solve this make sure you initiate the tempArray by the values of array's like following:
int tempArray[][] = new int[array.length + 1][array[0].length];
for(int i = 0; i < array.length; i++) {
for(int j = 0; j < array[0].length; j++) {
tempArray[i][j] = array[i][j];
}
}
Hopefully this will solve your problem. Happy coding!
You have not initialised the tempArray[][].
tempArray[tempArray.length][column] = total
change it to
tempArray[tempArray.length-1][column] = total
this will resolve the index out of bound issue.
public static int[][] sum(int[][] array) {
int tempArray[][] = new int[array.length + 1][array[0].length];
for (int column = 0; column < array[0].length; column++) {
int total = 0;
for (int row = 0; row < array.length; row++) {
tempArray[row][column] = array[row][column];
total += array[row][column];
}
tempArray[tempArray.length-1][column] = total; // resolves the index out of bound issue
}
return tempArray;
}
Mentioned solutions will not work in case if rows have different length. For example, if input array is
int[][] input = new int[][] { { 1, 2, 3 }, { 2, 3 } };
This solution eliminates such problem
public static int[][] sum(int[][] array) {
int[][] tempArray = new int[array.length + 1][];
int maxLength = 0;
for (int i = 0; i < array.length; i++) {
tempArray[i] = Arrays.copyOf(array[i], array[i].length);
maxLength = Math.max(maxLength, array[i].length);
}
tempArray[tempArray.length - 1] = new int[maxLength];
for (int i = 0; i < maxLength; i++ ) {
int total = 0;
for (int[] row : tempArray) {
if (i <= row.length - 1) {
total += row[i];
}
}
tempArray[tempArray.length - 1][i] = total;
}
return tempArray;
}
And the test
public static void main(String[] args) {
int[][] arr = new int[][] { { 1, 2, 3 }, { 2, 3 } };
System.out.println(Arrays.deepToString(sum(arr)));
// Output
// [[1, 2, 3], [2, 3], [3, 5, 3]]
}
I have this line of code to create a zigzag array, its fairly simple and I already have the code for it. here's the summary of the question:
This method creates and returns a new two-dimensional integer array, which in Java is really just a one-dimensional array whose elements are one-dimensional arrays of type int[]. The returned array must have the correct number of rows that each have exactly cols columns. This array must contain the numbers start, start + 1, ..., start + (rows * cols - 1) in its rows in order, except that the elements in each odd-numbered row must be listed in descending order.
For example, when called with rows = 4, cols = 5 and start = 4, this method should create and return the two-dimensional array whose contents are
4 5 6 7 8
13 12 11 10 9
14 15 16 17 18
23 22 21 20 19
I've tried talking with my colleagues but they can't spot the problem too
public class P2J1
{
public static int[][] createZigZag(final int rows, final int cols, int start)
{
final int[][] array = new int[rows][cols];
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
array[i][j] = start;
start++;
}
}
return array;
}
}
/// heres the tester program
#Test public void testCreateZigZag() {
Random rng = new Random(SEED);
CRC32 check = new CRC32();
for(int i = 0; i < TRIALS; i++) {
int rows = rng.nextInt(20) + 1;
int cols = rng.nextInt(20) + 1;
int start = rng.nextInt(100);
int[][] zig = P2J1.createZigZag(rows, cols, start);
assertEquals(rows, zig.length);
for(int j = 0; j < rows; j++) {
assertEquals(cols, zig[j].length);
for(int e: zig[j]) { check.update(e); }
}
}
assertEquals(3465650385L, check.getValue());
}
Your column index always goes from 0 to cols-1, in that order. You need to alternate the order every other row.
You can do this by using variables for the start, end, and increment of the inner loop and assign those variables based on the row index being odd or even.
Something like this (untested):
public static int[][] createZigZag(final int rows, final int cols, int start) {
final int[][] array = new int[rows][cols];
for (int i = 0; i < rows; i++) {
boolean backwards = ((i & 1) == 1);
final int jStart = backwards ? cols-1 : -1;
final int jEnd = backwards ? 0 : cols;
final int jStep = backwards ? -1 : 1;
for (int j = jStart; j != jEnd; j += jStep) {
array[i][j] = start;
start++;
}
}
return array;
}
You could also just write two different inner loops, selected on the same condition. One would fill starting from 0, the other would fill starting from cols-1 and going backwards.
public static int[][] createZigZag(final int rows, final int cols, int start) {
final int[][] array = new int[rows][cols];
for (int i = 0; i < rows; i++) {
if ((i & 1) == 1) {
for (int j = cols-1; j >= 0; j--) {
array[i][j] = start;
start++;
}
} else {
for (int j = 0; j < cols; j++) {
array[i][j] = start;
start++;
}
}
}
return array;
}
"Find the maximum element (s) in the matrix and remove from the matrix all the rows and columns containing it".
I made the methods. In one, I find the largest number in the matrix. And in the second, I delete from the matrix the row and column that contains the largest number. But it works correctly only if the largest number is the only one. How to make, that deleted all lines and all columns in which the greatest number contains?
private void deleteRowCol() {
int[][] matrix = getMatrix();
int max = matrix[0][0];
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[0].length; j++) {
if (max < matrix[i][j]) {
max = matrix[i][j];
}
}
}
int[] m = findIdMax(matrix, max);
int[][] outMatrix = new int[matrix.length - 1][matrix[0].length - 1];
int r = 0;
for (int i = 0; i < outMatrix.length; i++) {
if (i > m[0] - 1) {
r = 1;
}
int c = 0;
for (int j = 0; j < outMatrix[0].length; j++) {
if (j > m[1] - 1) {
c = 1;
}
outMatrix[i][j] = matrix[i + r][j + c];
}
}
System.out.println(" ");
outputMatrix(outMatrix);
}
private int[] findIdMax(int[][] matrix, int max) {
int[] id = {0, 0};
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[0].length; j++) {
if (max == matrix[i][j]) {
id[0] = i;
id[1] = j;
}
}
}
return id;
}
expected output:
with this matrix
4 2 0 -3
4 -1 4 1
0 2 -4 3
-4 -1 -4 -2
should bring
-2 3
-1 -2
I haven't been able to find a fix for your current code. One issue is that you always assume 1 row and 1 column are deleted with int[][] outMatrix = new int[matrix.length - 1][matrix[0].length - 1];. If I put a loop around your code it would fail if the max is for example at positions 1,2 and 1,4 in the matrix (which should remove only 1 row, but 2 columns).
So perhaps someone else could take a closer look at your implementation and see a straight-forward fix without changing too much. Instead, I've thought about the use case from scratch and tried to complete the task myself. I ended up with the following code:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
class Main{
private Set<Integer> rowsToDelete,
columnsToDelete;
public static void main(String[] a){
Main program = new Main();
int[][] matrix = program.getMatrix();
System.out.println("Before:");
program.prettyPrintMatrix(matrix);
System.out.println();
int[][] modifiedMatrix = program.deleteRowCol(matrix);
System.out.println("After:");
program.prettyPrintMatrix(modifiedMatrix);
}
private int[][] getMatrix(){
// Test:
return new int[][]{
{ 4, 2, 0,-3},
{ 4,-1, 4, 1},
{ 0, 2,-4, 3},
{-4,-1,-4,-2}
};
}
private int[][] deleteRowCol(int[][] matrix) {
int max = findMax(matrix);
determineCoordinatesMax(matrix, max);
// Some debug prints:
System.out.println("Maximum: "+max);
System.out.println("Rows to delete: "+rowsToDelete);
System.out.println("Columns to delete: "+columnsToDelete);
System.out.println();
int[][] modifiedMatrix = deleteRows(matrix);
modifiedMatrix = deleteColumns(modifiedMatrix);
return modifiedMatrix;
}
private int findMax(int[][] matrix){
int max = matrix[0][0];
for(int[] row : matrix){
for(int value : row){
if(value > max){
max = value;
}
}
}
return max;
}
private void determineCoordinatesMax(int[][] matrix, int max) {
rowsToDelete = new HashSet<>();
columnsToDelete = new HashSet<>();
for(int r=0; r<matrix.length; r++){
for(int c=0; c<matrix[r].length; c++){
if(matrix[r][c] == max){
rowsToDelete.add(r);
columnsToDelete.add(c);
}
}
}
}
private int[][] deleteRows(int[][] matrix){
int rowsToLeave = matrix.length - rowsToDelete.size();
int[][] modifiedMatrix = new int[rowsToLeave][];
int i = 0;
for(int r=0; r<matrix.length; r++){
if(!rowsToDelete.contains(r)){
modifiedMatrix[i] = matrix[r];
i++;
}
}
return modifiedMatrix;
}
private int[][] deleteColumns(int[][] matrix){
int columnsAlreadyDeleted = 0;
for(int columnToDelete : columnsToDelete){
// Delete the columns one by one:
int[][] modifiedMatrix = new int[matrix.length][matrix[0].length - 1];
for(int r=0; r<matrix.length; r++){
int i=0;
for(int c=0; c<matrix[r].length; c++){
if(c != columnToDelete - columnsAlreadyDeleted){
modifiedMatrix[r][i] = matrix[r][c];
i++;
}
}
}
columnsAlreadyDeleted++;
matrix = modifiedMatrix;
}
return matrix;
}
private void prettyPrintMatrix(int[][] matrix){
for(int[] row : matrix){
System.out.println(Arrays.toString(row));
}
}
}
The deletion of the columns could use some tweaking, since I now have three nested loops (loop over the columns to delete; inner loop over the matrix-rows; inner loop over the matrix-columns). But it works, and removes the rows and columns of the int[][] as expected.
You can see it in action here: Try it online.
So I have to write a method that goes in array and goes from i to j rows and copies these rows to a new array. This is what I come up so far
public static void getRows(int i, int j, int[][] array){
int another[] = new int[j-i];
int n = 0;
for (int k = 0; k < array.length; k++){
while (i <= j){
if (k == i){
another[n] = array[k][0];
}
i++;
}
}
}
First, you aren't returning or printing anything. Second, to copy multiple rows from your input your returned array should be 2d (not 1d). Create a new int[][] of j - i rows. Then copy from array to the new array. Something like,
public static int[][] getRows(int i, int j, int[][] array) {
int[][] ret = new int[j - i][];
for (int k = i; k < j; k++) {
ret[k - i] = new int[array[k].length];
for (int m = 0; m < ret[k - i].length; m++) {
ret[k - i][m] = array[k][m];
}
}
return ret;
}
Then you can invoke it (and print the results) with something like
public static void main(String[] args) {
int[][] t = { { 0, 1 }, { 2, 3 }, { 4, 5 } };
System.out.println(Arrays.deepToString(getRows(1, 3, t)));
}
Which outputs
[[2, 3], [4, 5]]
#Elliot I did it like this :)
public static int[][] getRows(int i, int j, int[][] array){
int[][] another = new int[j-i+1][];
while (i <=j){
for (int k = 0; k < another.length; k++){
another[k]=array[i];
i++;
}
}
return another;
}