2-D Array (row and column) - java

The program below (thanks to Sundial) computes the area of a rectangle
public class ComputeTheArea {
public static int areaOfTheRectangle (char[][] table, char ch) {
int[] first = new int[2];
int[] last = new int[2];
for (int i=0; i<3; i++) {
for (int j=0; j<4; j++) {
if(grid[i][j]==ch) {
first[0] = i;
first[1] = j;
}
}
}
for (int i=2; i>=0; i--) {
for (int j=3; j>=0; j--) {
if(grid[i][j]==ch) {
last[0] = i;
last[1] = j;
}
}
}
int answer = ((Math.max(first[0]+1,last[0]+1) - Math.min(first[0]+1,last[0]+1)) *
(Math.max(first[1]+1,last[1]+1) - Math.min(first[1]+1,last[1]+1)));
return answer;
}
However, when it is run, it outputs the wrong answer. I know there is something wrong with the for loop. I'm new in Java and I need your help for me to fix the method. Please and thank you very much!
EDIT: I edited the code to conform to Michael's answer.

First of all, you don't search all the elements in the matrix with your first loop.
Secondly, you don't break when you found a match.
Also, this approach is a bit flawed. For example, see this matrix:
a b c b
a _ c d
x z b a
Here you wouldn't know which b to stop at at the first row to get the entire b square.
If you instead just loop through the entire matrix once and saves the maximum and minimum (first and last) x and y coordinates, the area can be calculated very easily. See this code:
public static int charArea (char[][] grid, char ch) {
int[] first = new int[] {100, 100};
int[] last = new int[] {-1, -1};
for (int i=0; i<3; i++) {
for (int j=0; j<4; j++) {
if(grid[i][j]==ch) {
first[0] = Math.min(i, first[0]);
first[1] = Math.min(j, first[1]);
last[0] = Math.max(i, last[0]);
last[1] = Math.max(j, last[1]);
}
}
}
int answer = (last[0] - first[0] + 1) * (last[1] - first[1] + 1);
return answer;
}

The for loops should probably break once they find the character.
The first for loop sets j=i. That should probably be j=0 instead.
I don't think the length calculation is correct. A 1 should be added to both terms. I.e. the length of something with first=0 and last=3 should be last+1-first=4, not 3 as it would be now.

Related

How do I read through a 2D array without searching out of bounds?

I have a 2D array acting as a grid.
int grid[][] = new int[5][5];
How do I search through the grid sequentially as in (0,0), (1,0), (2,0), (3,0), (4,0) then (0,1), (1,1), (2,1) ... without getting any array out of bounds exceptions.
I'm new to programming and I just can't get my head around how to do this.
You know your lengths, now use a for loop to circle through the array.
for (int i = 0;i<5;i++){
for (int j = 0;i<5;i++){
int myInt = grid[i][j];
//do something with my int
}
}
To get the lengths at runtime you could do
int lengthX = grid.length; //length of first array
int lengthY = 0;
if ( lengthX>0){ //this avoids an IndexOutOFBoundsException if you don't know if the array is already initialized yet.
lengthY = grid[0].length; //length of "nested" array
}
and then do the for loop with lengthX and lengthY.
You will need two nested loop in order to access the two dimensions of your array:
int grid[][] = new int[5][5];
for(int i = 0; i < 5; i++ ) {
for(int j = 0; j < 5; j++ ) {
int value = grid[i][j];
}
}
Use 2 forloops like the following example:
for(int i = 0; i < 5; i++){
for(int j = 0; j < 5; j++){
System.out.println(grid[i][j]);
}
}
Also i would suggest that when initializing an array to write it like this:
int[][] grid = new int[5][5]; // note the double brackets are after int and not grid
Try this:
for(int i=0;i<5;i++)
{
for(int j=0;j<5;j++)
{
System.out.println(grid[j][i]);
}
}
This code (like the other answers) uses two for loops.
It does however add some handling of edge-cases
static int[] find(int[][] mtx, int valueToLookFor)
{
int rows = mtx.length;
if(rows == 0)
return new int[]{-1,-1};
int cols = mtx[0].length;
if(cols == 0)
return new int[]{-1, -1};
for(int r=0;r<rows;r++)
{
for(int c=0;c<cols;c++)
{
if(mtx[r][c] == valueToLookFor)
return new int[]{r,c};
}
}
return new int[]{-1,-1};
}

Sudoku debugging issue

I'm working on a program that is supposed to take as input a solved Sudoku Puzzle and return if it is a valid solution or not (true or false).
My code is written and running with a few helper methods.
The isSolution method runs through 4 different things to check if the solution is valid or not.
I've written a valid solution as input that should return true.
When I check each of these 4 elements separately, they return true, when I check them together, they return false (which is wrong)
I've spent hours testing them separately, together and in different combinations.
I've tried with different inputs.
I can't figure out why it's returning false when it should be returning true.
Any help would be amazingly appreciated! Thanks
public static void main(String[] args){
int [][] solvedPuzzle = {
{8,3,5,4,1,6,9,2,7},
{2,9,6,8,5,7,4,3,1},
{4,1,7,2,9,3,6,5,8},
{5,6,9,1,3,4,7,8,2},
{1,2,3,6,7,8,5,4,9},
{7,4,8,5,2,9,1,6,3},
{6,5,2,7,8,1,3,9,4},
{9,8,1,3,4,5,2,7,6},
{3,7,4,9,6,2,8,1,5}
};
System.out.println(isSolution(solvedPuzzle));
}
////// Checks if the input is a valid sudoku solution
/* The solvedPuzzle input is a valid solution, so this method should return true.
* Each of the elements in this method return true when tested individually, but for some reason,
* when I run them all together, the method returns false
*/
public static boolean isSolution(int [][] solvedPuzzle){
//Checks if the rows and columns have 9 ints
if (solvedPuzzle.length != 9 || solvedPuzzle[0].length !=9){
return false;
}
//Checks if every column is made up of unique entries
for (int j = 0; j < 9; j++){
if (uniqueEntries(getColumn(solvedPuzzle, j)) !=true){
System.out.println("HERE!"); //these are just here to try to figure out WHERE I've gone wrong
return false;
}
}
//Checks if every row is made up of unique entries
for (int i = 0; i < 9; i++){
if (uniqueEntries(solvedPuzzle[i]) !=true){
System.out.println("HERE!!!");
return false;
}
}
//Checks if every sub 3x3 grid is made up of unique entries
for (int x = 0; x < 9; x = x+3){
for (int y = 0; y < 9; y = y+3){
if (uniqueEntries(flatten(subGrid(solvedPuzzle, x,y,3))) != true){
System.out.println("HERE22");
return false;
}
}
}
return true;
}
///Below are the helper methods
////// Creates a smaller grid of size m starting at indexI,indexJ (x,y).
public static int [][] subGrid(int [][] original, int indexI, int indexJ, int m){
int [][] subGrid = new int [m][m];
for (int i = indexI; i < indexI+m ; i++){
for (int j = indexJ; j < indexJ+m ; j++){
subGrid [i - indexI][j - indexJ] = original[i][j];
}
}
return subGrid;
}
////// Sorts the intergers in a 1D array in asceding order
public static int [] sort(int [] originalArray){
int temp;
for(int i = 0; i < originalArray.length - 1; i++){
for(int j = 0; j < originalArray.length - 1; j++){
if(originalArray[j] > originalArray[j+1]){
temp = originalArray[j];
originalArray[j] = originalArray[j+1];
originalArray[j+1] = temp;
}
}
}
return(originalArray);
}
////// Checks if the intergers in a 1D array are all unique by first using the sort method
public static boolean uniqueEntries(int [] original){
int [] sorted = sort(original);
for (int i = 0; i < original.length-1; i++){
if (sorted[i+1] == sorted[i]) {
return false;
}
}
return true;
}
////// Takes a 2D array where each subarray is of the same size and creates a 1D array made up of the i-th element of each sub array
public static int [] getColumn(int [][] original, int indexJ){
int [] column = new int[original[0].length];
for (int i = 0; i < original[0].length; i++){
column[i] = original[i][indexJ];
}
return column;
}
////// takes a 2D array and flattens it into a 1D array
public static int [] flatten(int [][] original){
int [] flattenedArray = new int[original.length*original[0].length];
int counter = 0;
for (int i = 0; i < original.length; i++){
for(int j = 0; j < original.length; j++) {
flattenedArray[counter] = original[i][j];
counter++;
}
}
return flattenedArray;
}
if you check your puzzle before and after running //Checks if every row is made up of unique entries you will see that you are actually changing the original format of your puzzle. So the next test is not going to run over the original puzzle but a sorted one! If you add a simple loop before and after the second test you will understand what I am talking about
for (int i = 0; i < 9; i++){ //ADD THAT LOOP BEFORE AND AFTER THE TEST
for (int j = 0; j<9; j++) {
System.out.print(solvedPuzzle[i][j]);
}
System.out.println();
}
System.out.println('\n');
//Checks if every row is made up of unique entries
for (int i = 0; i < 9; i++){
if (uniqueEntries(solvedPuzzle[i]) !=true){
System.out.println("HERE!!!");
return false;
}
}
for (int i = 0; i < 9; i++){
for (int j = 0; j<9; j++) {
System.out.print(solvedPuzzle[i][j]);
}
System.out.println();
}
the code above will help you visualise what the puzzle looks before and after the test. A test should never change the format/contents/attributes of anything tested. The results of the above will be:
835416927
296857431
417293658
569134782
123678549
748529163
652781394
981345276
374962815
123456789
123456789
123456789
123456789
123456789
123456789
123456789
123456789
123456789
As you can see the original puzzle is not "original" anymore.
So as I told you on my comment, flipping the tests around will NOT actually fix the problem. Instead the bug will still be produced; but without any tests to run after it is not going to affect the CURRENT code.
Hope that helps
EDIT: I don't know if I will be online later on; so in the case that even that hint didn't help you find the bug so I am also going to give you the solution :p
The issue is that you are using the sort() method that doesn't ONLY return the array sorted BUT ALSO actually sorts the input array! SO in order to avoid that you simply need to pass in a copy of the array instead of the array itself whenever you are calling the sort method:
////// Checks if the intergers in a 1D array are all unique by first using the sort method
public static boolean uniqueEntries(int [] original){
int [] sorted = sort(original.clone()); //pass in a copy of the array
for (int i = 0; i < original.length-1; i++){
if (sorted[i+1] == sorted[i]) {
return false;
}
}
return true;
}

Array in the reverse order [duplicate]

This question already has answers here:
How do I reverse an int array in Java?
(47 answers)
Closed 8 years ago.
I have an array of n elements and these methods:
last() return the last int of the array
first() return the first int of the array
size() return the length of the array
replaceFirst(num) that add the int at the beginning and returns its position
remove(pos) that delete the int at the pos
I have to create a new method that gives me the array at the reverse order.
I need to use those method. Now, I can't understand why my method doesn't work.
so
for (int i = 1; i
The remove will remove the element at the position i, and return the number that it is in that position, and then with replaceFirst will move the number (returned by remove) of the array.
I made a try with a simple array with {2,4,6,8,10,12}
My output is: 12 12 12 8 6 10
so if I have an array with 1,2,3,4,5
for i = 1; I'm gonna have : 2,1,3,4,5
for i=2 >3,2,1,4,5
etc
But it doesn't seem to work.
Well, I'll give you hints. There are multiple ways to reverse an array.
The simplest and the most obvious way would be to loop through the array in the reverse order and assign the values to another array in the right order.
The previous method would require you to use an extra array, and if you do not want to do that, you could have two indices in a for loop, one from the first and next from the last and start swapping the values at those indices.
Your method also works, but since you insert the values into the front of the array, its going to be a bit more complex.
There is also a Collections.reverse method in the Collections class to reverse arrays of objects. You can read about it in this post
Here is an code that was put up on Stackoverflow by #unholysampler. You might want to start there: Java array order reversing
public static void reverse(int[] a)
{
int l = a.length;
for (int j = 0; j < l / 2; j++)
{
int temp = a[j]
a[j] = a[l - j - 1];
a[l - j - 1] = temp;
}
}
int[] reverse(int[] a) {
int len = a.length;
int[] result = new int[len];
for (int i = len; i > 0 ; i--)
result[len-i] = a[i-1];
return result;
}
for(int i = array.length; i >= 0; i--){
System.out.printf("%d\n",array[i]);
}
Try this.
If it is a Java array and not a complex type, the easiest and safest way is to use a library, e.g. Apache commons: ArrayUtils.reverse(array);
In Java for a random Array:
public static void reverse(){
int[] a = new int[4];
a[0] = 3;
a[1] = 2;
a[2] = 5;
a[3] = 1;
LinkedList<Integer> b = new LinkedList<Integer>();
for(int i = a.length-1; i >= 0; i--){
b.add(a[i]);
}
for(int i=0; i<b.size(); i++){
a[i] = b.get(i);
System.out.print(a[i] + ",");
}
}
Hope this helps.
Reversing an array is a relatively simple process. Let's start with thinking how you print an array normally.
int[] numbers = {1,2,3,4,5,6};
for(int x = 0; x < numbers.length; x++)
{
System.out.println(numbers[x]);
}
What does this do? Well it increments x while it is less than numbers.length, so what is actually happening is..
First run : X = 0
System.out.println(numbers[x]);
// Which is equivalent to..
System.out.println(numbers[0]);
// Which resolves to..
System.out.println(1);
Second Run : X = 1
System.out.println(numbers[x]);
// Which is equivalent to..
System.out.println(numbers[1]);
// Which resolves to..
System.out.println(2);
What you need to do is start with numbers.length - 1, and go back down to 0. To do this, you need to restructure your for loop, to match the following pseudocode..
for(x := numbers.length to 0) {
print numbers[x]
}
Now you've worked out how to print, it's time to move onto reversing the array. Using your for loop, you can cycle through each value in the array from start to finish. You'll also be needing a new array.
int[] revNumbers = new int[numbers.length];
for(int x = numbers.length - 1 to 0) {
revNumbers[(numbers.length - 1) - x] = numbers[x];
}
int[] noArray = {1,2,3,4,5,6};
int lenght = noArray.length - 1;
for(int x = lenght ; x >= 0; x--)
{
System.out.println(noArray[x]);
}
}
int[] numbers = {1,2,3,4,5};
int[] ReverseNumbers = new int[numbers.Length];
for(int a=0; a<numbers.Length; a++)
{
ReverseNumbers[a] = numbers.Length - a;
}
for(int a=0; a<ReverseNumbers.Length; a++)
Console.Write(" " + ReverseNumbers[a]);
int[] numbers = { 1, 2, 3, 4, 5, 6 };
reverse(numbers, 1); >2,1,3,4,5
reverse(numbers, 2); >3,2,1,4,5
public int[] reverse(int[] numbers, int value) {
int index = 0;
for (int i = 0; i < numbers.length; i++) {
int j = numbers[i];
if (j == value) {
index = i;
break;
}
}
int i = 0;
int[] result = new int[numbers.length];
int forIndex = index + 1;
for (int x = index + 2; x > 0; x--) {
result[i] = numbers[forIndex--];
++i;
}
for (int x = index + 2; x < numbers.length; x++) {
result[i] = numbers[x];
++i;
}
return result;
}

Java - Adding Rows is there a more efficient way?

Below is the code, I am just wondering if others are coding it differently. Maybe I can make small changes. Thanks in advance!
public class addRow {
public static int[][] insert(int [][] a, int [] row, int index){
int [][] x = new int[a.length+1][a.length];
int [] temp;
for(int i=0; i<x.length-1; i++)
{
x[i] = a[i];
if(i == index)
{
temp = a[i];
x[i] = row;
x[i+1] = temp;
}
}
return x;
}
public static void main(String[] args){
int[][] a = {{1,2,3},{4,5,6},{10,11,12}};
int[] row = {7,8,9};
int [][] b = insert(a,row ,2);
for(int r=0; r < b.length; r++){
for(int c=0;c< b[r].length; c++){
System.out.print(b[r][c] + " ");
}System.out.println();
}
}
}
System.arraycopy is your answer.
http://docs.oracle.com/javase/6/docs/api/java/lang/System.html#arraycopy%28java.lang.Object,%20int,%20java.lang.Object,%20int,%20int%29
It uses native code to copy arrays in memory directly, making it much more efficient.
Your loop doesn't do what you think it does. When you swap rows i and i+1 in x, the next iteration of the loop will overwrite the element you put in x[i+1] on the previous iteration. You need to keep an extra index (or split your loop) to keep track of the difference in positions between a and x after hitting index. A better approach, though, is to use System.arraycopy.
Also, there's no reason to allocate space for the rows of x in its initializer, since you are assigning elements of a (or row) to them anyway. My version of your method is:
public static int[][] insert(int [][] a, int [] row, int index){
int[][] x = new int[a.length + 1][]; // no second dimension
System.arraycopy(a, 0, x, 0, index);
x[index] = row;
System.arraycopy(a, index, x, index + 1, a.length - index);
return x;
}
Just because your code seems to be working for 1 case, it doesn't mean it proper. You'd have tried out the other cases as well.
You need to make the following changes in your method for it to work properly.
public static int[][] insert(int [][] a, int [] row, int index){
int [][] x = new int[a.length+1][a.length];
int j = 0; // New counter for array `a`
// Also `temp` array removed. Not required at all.
for (int i = 0; i < x.length; i++) {
x[i] = a[j];
if (i == index) {
x[i] = row;
x[i + 1] = a[j];
} else {
j++;
}
}
return x;
}
This is the maximum you can optimize your code as such, without changing the base of your code.
Now regarding optimizing it big time, as others suggested, you could use the System#arrayCopy.

How do I shift array elements up one position in java?

I am working on a java assignment where I need to delete an integer element in an array and shift the below elements up on space to keep them in order. The array is currently random integers in descending order. I am not allowed to use array.copy because I will need to collect array usage information as part of the assignment. I have tried a ton of different ways of doing this but cannot seem to get it working.
public static void deletionArray(int anArray[], int positionToDelete) {
for (int j = anArray[positionToDelete] - 1; j < anArray.length; j++) {
System.out.println("j is " + j);
anArray[j] = anArray[j + 1];
}
displayArray(anArray);
}
You're iterating until anArray.length (exclusive), but inside the loop, you're accessing anArray[j + 1], which will thus be equal to anArray[anArray.length] at the last iteration, which will cause an ArrayIndexOutOfBoundsException.
Iterate until anArray.length - 1 (exclusive), and decide what should be stored in the last element of the array instead of its previous value.
You're also starting at anArray[positionToDelete] - 1, instead of starting at positionToDelete.
You have two bugs there.
Since this is an assignment, I won't give a complete answer - just a hint. Your loop definition is wrong. Think about this: what happens on the first and on the last iteration of the loop? Imagine a 5-element array (numbered 0 to 4, as per Java rules), and work out the values of variables over iterations of the loop when you're erasing element number, say, 2.
Use System.arraycopy faster than a loop:
public static void deletionArray( int anArray[], int positionToDelete) {
System.arraycopy(anArray, positionToDelete + 1, anArray,
positionToDelete, anArray.length - positionToDelete - 1);
//anArray[length-1]=0; //you may clear the last element
}
public static int[] deletionArray(int anArray[], int positionToDelete) {
if (anArray.length == 0) {
throw new IlligalArgumentException("Error");
}
int[] ret = new int[anArray.length - 1];
int j = 0;
for (int i = 0; i < anArray.length; ++i) {
if (i != positionToDelete) {
ret[j] = anArray[i];
++j;
}
}
return ret;
}
Why do we reserve a new array?
Because if don't, we would use C\C++-style array: an array and a "used length" of it.
public static int deletionArray(int anArray[], int positionToDelete, int n) {
if (n == 0) {
throw new IlligalArgumentException("Error");
}
for (int i = positionToDelete; i < n - 1; ++i) {
anArray[i] = anArray[i + 1];
}
return n - 1; // the new length
}
How's this ? Please note the comment, I don't think you can delete an element in an array, just replace it with something else, this may be useful : Removing an element from an Array (Java)
Updated with 'JB Nizet' comment :
public class Driver {
public static void main (String args []){
int intArray[] = { 1,3,5,6,7,8};
int updatedArray[] = deletionArray(intArray , 3);
for (int j = 0; j < updatedArray.length; j++) {
System.out.println(updatedArray[j]);
}
}
public static int[] deletionArray(int anArray[], int positionToDelete) {
boolean isTrue = false;
for (int j = positionToDelete; j < anArray.length - 1; j++) {
if(j == positionToDelete || isTrue){
isTrue = true;
anArray[j] = anArray[j + 1];
}
}
anArray[anArray.length-1] = 0; //decide what value this should be or create a new array with just the array elements of length -> anArray.length-2
return anArray;
}
}

Categories

Resources