2D Int Array Reversal in Java - java

The problem I am having is that I must create program that uses an object to reverse the elements of each row in a 2D Array and prints out the resulting matrix. The code I have only prints out the first 3 numbers of each row in reverse. This is my code:
class Reverse {
void matrixReverse(int[][] data) {
int row_val = data.length;
int col_val = data[0].length;
int[][] data_reverse = new int[row_val][col_val];
for(int row = row_val - 1; row >= 0; row--){
for(int col = col_val - 1; col >= 0; col--){
data_reverse[row_val - 1 - row][col_val - 1 - col] = data[row][col];
}
}
for(int row = 0; row < row_val; row++){
for(int col = 0; col < col_val; col++){
System.out.println(data_reverse[row][col]);
}
System.out.println();
}
}
}
public class ArrayReverse {
public static void main(String[] args) {
int[][] data = {
{3, 2, 5},
{1, 4, 4, 8, 13},
{9, 1, 0, 2},
{0, 2, 6, 3, -1, -8}
}; // Creates the array
Reverse reverse = new Reverse();
reverse.matrixReverse(data);
}
}
The output is:
6
2
0
0
1
9
4
4
1
5
2
3
As you can see, it's only printing the first 3 numbers of the rows but I need it to print all of them.

Your columns are variable width yet you are getting the width from the first row (which may not even exist!). You need to check the size of the array before accessing an element of it. You also have the array size parameters switched, start with row first.
To fix your specific problem, you need to set the col_val for each row inside the row loop.
void matrixReverse(int[][] data) {
int rowWidth = data.length;
int[][] reversedData = new int[rowWidth][];
for (int row = rowWidth - 1; row >= 0; row--) {
int colWidth = data[row].length;
int reverseRow = rowWidth - 1 - row;
reversedData[reverseRow] = new int[colWidth];
for (int col = colWidth - 1; col >= 0; col--) {
int reverseCol = colWidth - 1 - col;
reversedData[reverseRow][reverseCol] = data[row][col];
}
}
for (int row = 0; row < rowWidth; row++) {
int colWidth = reversedData[row].length;
for (int col = 0; col < colWidth; col++) {
System.out.println(reversedData[row][col]);
}
System.out.println();
}
}
P.S. row_val and col_val are bad names. They are widths not values and the naming convention in Java is colWidth and rowWidth not col_width or row_width.

Related

how to get minimum in 2d array java

I need help, please! I am building up the following code to extract the minimum value of each column of the distance
I have tried to compute the code but to no avail
public static void main(String[] args) {
int data[] = {2, 4, -10, 12, 3, 20, 30, 11};//,25,17,23}; // initial data
int noofclusters = 3;
int centroid[][] = new int[][]{
{0, 0, 0},
{2, 4, 30}
};
getCentroid(data, noofclusters, centroid);
}
public static int[][] getCentroid(int[] data, int noofclusters, int[][] centroid) {
int distance[][] = new int[noofclusters][data.length];
int cluster[] = new int[data.length];
int clusternodecount[] = new int[noofclusters];
centroid[0] = centroid[1];
centroid[1] = new int[]{0, 0, 0};
System.out.println("========== Starting to get new centroid =========");
for (int i = 0; i < noofclusters; i++) {
for (int j = 0; j < data.length; j++) {
//System.out.println(distance[i][j]+"("+i+","+j+")="+data[j]+"("+j+")-"+centroid[0][i]+"="+(data[j]-centroid[0][i]));
distance[i][j] = Math.abs(data[j] - centroid[0][i]);
System.out.print(distance[i][j] + " ,");
}
System.out.println();
}
int[] result = new int[distance.length];
for (int i = 0; i < distance.length; i++) {
//int min = distance;
int min = distance[i][0];
for (int j = 0; j < distance[0].length; j++) {
if (distance[i][j] < min) {
min = distance[i][j];
}
result[j] = min;
System.out.println(result[j] + ", ");
}
}
return result;
}
}
The result of the computation for distance gives
row 1: 0 ,2 ,12 ,10, 1 ,18 ,28 ,9
row 2: 2 ,0 ,14 ,8 , 1 ,16 ,26 ,7
row 3: 28,26,40 ,18, 27 ,10 ,0 ,19
I want to go through each column to get the minimum value
0 0 12 8 1 10 0 7
Thanks for your help in advance
To get the minimum value in each column, first, you need to iterate the column in the outer loop. By doing so, we can access the matrix colunm-wise.
Assign the first value of each column to a variable. Then iterate through the rows in the inner loop.
Check if the current value is less than the minimum value. If so, assign the smallest value to minimum.
When we use an array, we get an array of minimum values of the column.
To obtain the minimun value in each row, swap the loops and use min[i].
Below is an example code:
int []min = new int[column_lenght];
for(int j = 0; j < column_length; j++) {
min[j] = array[i][j];
for(int i = 0; i < row_length; i++) {
if(array[i][j] < min[j]) {
min[j] = array[i][j];
}
}
}
The min[] will contain the minimum value of each column.

Filling array with random digits in range

I am writing a sudoku board game generator. My code looks like this:
/**
* Created by szubansky on 3/9/16.
*/
public class SudokuBoard {
static int N = 9;
static int[][] grid = new int[N][N];
static void printGrid()
{
for (int row = 0; row < N; row++)
{
for (int col = 0; col < N; col++) {
System.out.printf("%5d", grid[row][col]);
}
System.out.println("\n");
}
}
private static boolean checkRow(int row, int num)
{
for( int col = 0; col < 9; col++ )
if(grid[row][col] == num)
return false;
return true;
}
private static boolean checkCol(int col, int num)
{
for( int row = 0; row < 9; row++ )
if(grid[row][col] == num)
return false;
return true;
}
private static boolean checkBox(int row, int col, int num)
{
row = (row / 3) * 3;
col = (col / 3) * 3;
for(int r = 0; r < 3; r++)
for(int c = 0; c < 3; c++)
if(grid[row+r][col+c] == num)
return false;
return true;
}
public static boolean fillBoard(int row, int col, int[][] grid)
{
if(row==9) {
row = 0;
if (++col == 9)
return true;
}
if(grid[row][col] != 0)
return fillBoard(row+1, col, grid);
for(int num=1 + (int)(Math.random() * ((9 - 1) + 1)); num<=9; num++)
{
if(checkRow(row,num) && checkCol(col,num) && checkBox(row,col,num)){
grid[row][col] = num;
if(fillBoard(row+1, col, grid))
return true;
}
}
grid[row][col] = 0;
return false;
}
static public void main(String[] args){
fillBoard(0, 0, grid);
printGrid();
}
}
the problem is with generating numbers in fillBoard backtrack algorithm
it basically puts 0 everywhere
when I change the num range in for loop to 10 it goes smoothly but my numbers need to be lower than 9
i can also change the beginning of backtrack fillBoard to row==8 and col==8 and it fills it correctly with random numbers leaving last row and last column with "0".
how to generate random numbers from 1 to 9 and fill all my grid?
Try this :
public static void main(String[] args) {
int[][] grid = new int[9][9];
randomFillGrid(grid, 1, 10);
for (int[] row : grid) {
System.out.println(Arrays.toString(row));
}
}
static void randomFillGrid(int[][] grid, int randomNumberOrigin, int randomNumberBound) {
PrimitiveIterator.OfInt iterator = ThreadLocalRandom.current()
.ints(randomNumberOrigin, randomNumberBound)
.iterator();
for (int[] row : grid) {
for (int i = 0; i < row.length; i++) {
row[i] = iterator.nextInt();
}
}
}
EDIT :
if you want to generate a sudoku grid i.e.
the same single integer may not appear twice in the same row, column or in any of the nine 3×3 subregions of the 9x9 playing board.
import java.util.Arrays;
import java.util.Random;
import java.util.concurrent.ThreadLocalRandom;
/**
* #author FaNaJ
*/
public class SudokuGenerator {
private static final int N = 9;
private static final int S_N = 3;
public static int[][] generateSudokuGrid() {
int[][] grid = new int[N][N];
int[] row = {1, 2, 3, 4, 5, 6, 7, 8, 9};
for (int y = 0; y < N; y++) {
int attempts = 0;
do {
if (++attempts > 1000000) { // Oops! I know (sometimes :) it's not a good algorithm...
return generateSudokuGrid();
}
shuffleArray(row);
} while (!isAllowed(grid, y, row));
System.arraycopy(row, 0, grid[y], 0, N);
}
return grid;
}
static boolean isAllowed(int[][] grid, int y, int[] row) {
// check columns
for (int i = 0; i < y; i++) {
for (int j = 0; j < N; j++) {
if (grid[i][j] == row[j]) {
return false;
}
}
}
// check sub grids
int startY = (y / S_N) * S_N;
for (int x = 0; x < N; x++) {
int startX = (x / S_N) * S_N;
for (int j = startX; j < startX + S_N; j++) {
if (j != x) {
for (int i = startY; i < y; i++) {
if (grid[i][j] == row[x]) {
return false;
}
}
}
}
}
return true;
}
static void shuffleArray(int[] array) {
Random random = ThreadLocalRandom.current();
for (int i = N; i > 1; i--) {
swap(array, i - 1, random.nextInt(i));
}
}
static void swap(int[] array, int i, int j) {
int tmp = array[i];
array[i] = array[j];
array[j] = tmp;
}
public static void main(String[] args) {
int[][] grid = generateSudokuGrid();
for (int[] row : grid) {
System.out.println(Arrays.toString(row));
}
}
}
output :
[3, 4, 6, 9, 1, 2, 7, 8, 5]
[9, 7, 2, 3, 8, 5, 4, 1, 6]
[5, 8, 1, 6, 7, 4, 3, 2, 9]
[7, 6, 3, 8, 2, 9, 1, 5, 4]
[4, 9, 5, 1, 6, 7, 2, 3, 8]
[2, 1, 8, 4, 5, 3, 6, 9, 7]
[6, 2, 4, 5, 9, 1, 8, 7, 3]
[8, 5, 7, 2, 3, 6, 9, 4, 1]
[1, 3, 9, 7, 4, 8, 5, 6, 2]
You can use Random class of java.utilpackage to generate random numbers. Below is an example that generates random numbers between 1 to 9:
Random rn = new Random();
int answer = rn.nextInt(9) + 1;
Before I start let me say that this while I'm not going tell you outright what all of your errors are, I will help you narrow your search and suggest a method to further debug your code.
Now to your problem: your array populated only with zero.
Only two lines can populate your array.
The first sets a spot in the array to have a random int value between 1 and 9 inclusive. If this random number doesn't pass a series of tests then that spot in the array is set to zero.
If one of these testers never returns true, the array will be populated with only zeros.
This leaves 4 functions that could be bugged.
-checkRow
-checkCol
-checkBox
-fillBoard
The first 2 functions are relatively simple so I can say with certainty that those work fine.
This leads only the checkBox and fillBoard functions under suspicion as causes of your bug.
At this point, this is where the debugging comes in.
Both of these functions contain loops.
One method to see if your loop is working is to compare a set of expected changes/return values to those which are actually gotten from the program.
To do this, either use a debugger
(assert statement + java -ea program.java and or other debugger methods)
Or, you could add print statements within your loop which print your gotten values for various variables/functions.
In any case, welcome to Stacks Overflow.
You mention that you are using a backtrack algorithm so I thought this would be fun to use a backtrack algorithm and try to demonstrate what it is. Below is a mash-up of your code and mine. I tried to stick to what you were doing and only add/change what I felt like I needed to.
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* SudokuBoard.
*/
public class SudokuBoard {
// Dimension size of everything
static int N = 9;
// Sudoku grid
static int[][] grid = new int[N][N];
// Values that are potentially valid at each position in the sudoku grid
static int[][][] values = new int[N][N][N];
// Current index into the values
static int[][] index = new int[N][N];
/**
* Return a shuffled list of values from 1 - 9 with each value
* appearing only once.
*/
private static List<Integer> getValidValues(){
List<Integer> validValues = new ArrayList<>();
for(int i = 1; i < 10; i++){
validValues.add(i);
}
Collections.shuffle(validValues);
return validValues;
}
/**
* Populate the values array with shuffled values to choose from.
*/
private static void initValues()
{
for(int i = 0; i < values.length; i++){
for(int j = 0; j < values[i].length; j++){
List<Integer> validValues = getValidValues();
for(int k = 0; k < values[j].length; k++){
values[i][j][k] = validValues.get(k);
}
}
}
}
/**
* print the 2D sudoku grid.
*/
public static void printGrid()
{
for (int row = 0; row < N; row++)
{
for (int col = 0; col < N; col++) {
System.out.printf("%5d", grid[row][col]);
}
System.out.println("\n");
}
}
/**
* Check the row for validity.
*/
private static boolean checkRow(int row, int num)
{
for( int col = 0; col < 9; col++ )
if(grid[row][col] == num)
return false;
return true;
}
/**
* Check the col for validity.
*/
private static boolean checkCol(int col, int num)
{
for( int row = 0; row < 9; row++ )
if(grid[row][col] == num)
return false;
return true;
}
/**
* Check the box for validity.
*/
private static boolean checkBox(int row, int col,
int num, boolean testRowCol)
{
int theR = row;
int theC = col;
row = (row / 3) * 3;
col = (col / 3) * 3;
for(int r = 0; r < 3; r++) {
for (int c = 0; c < 3; c++) {
if (testRowCol) {
if (theR == row + r && theC == col + c){
continue;
}
}
if (grid[row + r][col + c] == num) {
return false;
}
}
}
return true;
}
/**
* Build the sudoku board.
*/
public static boolean fillBoard(int row, int col)
{
// if we are back at the beginning then success!
// but just for sanity we will check that its right.
if(row != 0 && col != 0){
if(row % 9 == 0 && col % 9 == 0){
return checkBoard();
}
}
// don't go out of range in the grid.
int r = row % 9;
int c = col % 9;
// get the index in the values array that we care about
int indexIntoValues = index[r][c];
// if the index is out of range then we have domain wipe out!
// lets reset the index and try to back up a step. Backtrack!
if(indexIntoValues > 8){
index[r][c] = 0;
// there are a few cases to cover
// if we are at the beginning and the index is out
// of range then failure. We should never get here.
if(row == 0 && col == 0) {
return false;
}
grid[r][c] = 0;
// if the row is at 0 then back the row up to row - 1 and
// the col - 1
if(r == 0 && c > 0) {
return fillBoard(row - 1, col - 1);
}
// if the row is greater than 0 then just back it up by 1
if(r > 0){
return fillBoard(row - 1, col);
}
}
index[r][c] += 1;
// get the value that we care about
int gridValue = values[r][c][indexIntoValues];
// is this value valid
if(checkRow(r,gridValue) && checkCol(c,gridValue) &&
checkBox(r,c,gridValue,false)){
// assign it and move on to the next one
grid[r][c] = gridValue;
return fillBoard(row+1, r == 8 ? col + 1 : col);
}
// the value is not valid so recurse and try the next value
return fillBoard(row, col);
}
/**
* This is a sanity check that the board is correct.
* Only run it after a solution is returned.
*/
private static boolean checkBoard(){
//the grid is N X N so just use N as the condition.
//check rows are ok.
for(int i = 0; i < N; i++){
for(int j = 0; j < N; j++){
//for each of the elements in the row compare against
//every other one except its self.
int toTest = grid[i][j];
//check that the digits in the elements are in the valid range.
if(toTest > 9 || toTest < 1)
return false;
for(int k = 0; k < N; k++){
//don't test me against myself
if(k == j)
continue;
//if i am equal to another in the row there is an error.
if(toTest == grid[i][k])
return false;
}
}
}
//check the cols are ok.
for(int i = 0; i < N; i++){
for(int j = 0; j < N; j++){
//flip i and j to go for cols.
int toTest = grid[j][i];
for(int k = 0; k < N; k++){
if(k == j)
continue;
if(toTest == grid[k][i])
return false;
}
}
}
//check blocks are ok
for(int i = 0; i < N; i++){
for(int j = 0; j < N; j++){
int toTest = grid[i][j];
if(!checkBox(i, j, toTest, true))
return false;
}
}
return true;
}
static public void main(String[] args){
initValues();
if(fillBoard(0, 0))
printGrid();
else
System.out.println("Something is broken");
}
}
So the main things that I added were two multidimensional arrays one is a values list, and the other is a current index into that values list. So the values array keeps a list of all of the valid values that each cell can have. I shuffled the values to give the random feel that you were looking for. We don't really care about value ordering here for any performance reasons, but we want it to be "random" in order to get a different board from run to run. Next the index array keeps track of where you are in the values array. At any point that your index in the index array goes out of bounds, that means that none of the values will work. This is the point that you need reset the index to zero and go back to the cell you came from to try a new value there. That is the backtracking step. I kept moving through the array sequential as you did but its not necessary. I think you could actually go to the variable that has the least amount of valid values, so the highest index in this case, and the search should be faster, but who cares right now, it's a small search, the depth is 81 and you win! I also included a sanity check that the board is valid.
Here is an output:
1 3 2 5 7 6 4 9 8
7 5 8 1 9 4 3 2 6
6 4 9 8 2 3 1 7 5
8 6 3 2 5 9 7 1 4
5 7 4 6 3 1 9 8 2
9 2 1 4 8 7 5 6 3
4 9 7 3 6 8 2 5 1
3 8 5 7 1 2 6 4 9
2 1 6 9 4 5 8 3 7
I hope this helps you in some way, this was a fun one.

Finding row with the highest range in 2d array Java

public static void main(String[] args)
{
int[][] data = {{1, 2, 3}, {2, 3, 9}, {3, 4, 5}};
int row = 0;
int maxRow = data[row][0];
int minRow = data[row][0];
int rowCounter = 0;
int rowRange = 0;
for (row = 0; row < data.length; row++)
{
for (int col = 0; col < data[row].length; col++)
{
if (data[row][col] > maxRow)
{
maxRow = data[row][col];
}
else if (data[row][col] < minRow)
{
minRow = data[row][col];
}
}
rowCounter++;
rowRange = maxRow - minRow;
}
System.out.printf("The row with the greatest range is row #%d the range is %d%n", rowCounter, rowRange);
}
I'm looking to find the row with the greatest range and what row number its in, but I'm having some trouble.
The answer should be a "range of 7 row number 1"
With the code above I'm only getting the overall max range and row of everything. Any ideas?
Note: This is a small scale example I want to carry over to a huge array file.
By doing:
rowRange = maxRow - minRow;
you're overriding the range again and again.
Do instead:
int tmpRowRange = maxRow - minRow;
if (tmpRowRange > rowRange)
rowRange = tmpRowRange;
This way, you'll override rowRange only with values that are greater than the previous ones, which will leave you at the end of the iteration with the maximum range.

Sum of int[][] rows as int[] (Java)

I'm trying to take the sum of each row in a 2d array and store the values in a new array. Right now sum[] is only returning the values stored in the first row. Please help me understand what I'm missing here.
public static int[] rowSum(int[][] matrix) //find sum of digits in given row
{
int[] sum = new int[6];
for (int col = 0; col < ARRAY_LENGTH; col++)
{
for (int row = 0; row < ARRAY_LENGTH; row++)
{
sum[row] += matrix[col][row];
}
}
return sum;
}
Since you use Java 8 you can use:
return Arrays.stream(matrix) // Stream<int[]>
.mapToInt(row -> Arrays.stream(row).sum()) // IntStream
.toArray(); // int[]
Following code works for 2D arrays of different size as well.
public static void main(String[] args) {
int[][] matrix = {
{2, 3, 4, 5, 6, 7, 8, 9}, // 8 elements
{2, 1, 4, 5, 7, 2, 86} // 7 elements
};
int[] sum = rowSum(matrix);
for (int i : sum) {
System.out.println(i);
}
}
public static int[] rowSum(int[][] matrix) //find sum of digits in given row
{
int[] sum = new int[matrix.length];
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[i].length; j++) {
sum[i] = sum[i] + matrix[i][j];
}
}
return sum;
}
simple
public static int[] rowSum(int[][] matrix) //find sum of digits in given row
{
int[] sum = new int[6];
ARRAY_LENGTH = 6;
for (int col = 0; col < ARRAY_LENGTH; col++)
{
for (int row = 0; row < ARRAY_LENGTH; row++)
{
sum[col] += matrix[col][row];
}
}
}
careful with ARRAY_LENGTH

method to do in place reversal of columns in a 2D array in Java

The problem is given a 2D array write a method to reversal of columns. If possible, do it in-place
I have implemented and it works fine.but it is not in-place.It uses auxillary storage, is it possible to reverse columns of a 2D array without using matrix.
Here is my code:
public static int[][] reverseColumns(int[][] matrix){
int rows=matrix.length;
int cols=matrix[0].length;
int temp=0;
int[][] result= new int[rows][cols];
for (int row=rows-1; row >=0; row--){
for (int col=0;col<cols;col++){
result[row][col]=matrix[temp][col];
}
temp++;
}
return result;
}
public static void print2DArray(int[][] result){
for (int i=0; i < result.length;i++){
System.out.println(Arrays.toString(result[i]));
}
}
public static void main(String[] args)
{
int[][] matrix = {
{1,2,3,4},
{5,6,7,8},
{9,10,11,12},
{13,14,15,16}
int[][] result = reverseColumns(matrix);
print2DArray(result);
System.out.println()
};
output is :
[13, 14, 15, 16]
[9, 10, 11, 12]
[5, 6, 7, 8]
[1, 2, 3, 4]
I have followed the semantics of reversal of cols and rows as what you suggested:
1 2 3 7 8 9
4 5 6 _______column reversal_______ 4 5 6 (vertically reversed)
7 8 9 1 2 3
1 2 3 3 2 1
4 5 6 _______row reversal__________ 6 5 4 (horizontally reversed)
7 8 9 9 8 7
It is possible to do both in-place:
for the horizontal (row reversal) it is straightforward. For the vertical (col reversal), it needs some more understanding. Here the methods are; take an example matrix and try to follow the steps, you will understand
public static void reverseColumnsInPlace(int[][] matrix){
for(int col = 0;col < matrix[0].length; col++){
for(int row = 0; row < matrix.length/2; row++) {
int temp = matrix[row][col];
matrix[row][col] = matrix[matrix.length - row - 1][col];
matrix[matrix.length - row - 1][col] = temp;
}
}
}
public static void reverseRowsInPlace(int[][] matrix){
for(int row = 0; row < matrix.length; row++){
for(int col = 0; col < matrix[row].length / 2; col++) {
int temp = matrix[row][col];
matrix[row][col] = matrix[row][matrix[row].length - col - 1];
matrix[row][matrix[row].length - col - 1] = temp;
}
}
}
The trick is to have a counter variable, say row,
then loop only to the middle of the array, and do
tmp = matrix[row];
matrix[row]=matrix[rows-1-row];
matrix[rows-1-row]=tmp;
where rows is the total count.
I'll let you figure out the type of tmp.
This is using just a constant auxiliary storage,
because tmp is just a reference (4 bytes in Java).
public static int[][] reverseColumns(int[][] matrix){
int rows=matrix.length;
int[] temp=null;
for (int row=rows-1; row>=rows/2; row--){
temp = matrix[row];
matrix[row]=matrix[rows-1-row];
matrix[rows-1-row] = temp;
}
return matrix;
}
This might help you with in-place exchanges:
private void swap(int[][] A, int row1, int col1, int row2, int col2) {
int tmp = A[row1][col1];
A[row1][col1] = A[row2][col2];
A[row2][col2] = tmp;
}

Categories

Resources