I have the following 2D array and I want to compare all the columns with each other.
int [][] myarray={{1,2,3},{1,2,3},{1,2,3}};
So what I want to see is if column 1 (all 1's) is equal to the values in column 2 (all 2's).
Ps. the array size is not just limited to this.
It's not quite clear from your question whether you want to compare all columns to each other, or just a single column to another single column (for example column 1 to column 2). Assuming you meant the latter, you could do this.
public boolean columnsIdentical(int[][] array, int colIndex1, int colIndex2) {
for (int row = 0; row < array.length; row++ ) {
if (array[row][colIndex1] != array[row][colIndex2]) {
return false;
}
}
return true;
}
for (int i=0;i<myarray[0].length;i++) {
int comp=myarray[0][i];
for (int j=1;j<myarray.length;j++) {
if (myarray[j][i] != comp) {
// no match
} else {
// match
}
}
}
To test all pairs of columns you need 3 loops
Innermost compares elements of columns A and B
Middle loops through B, skipping columns already checked
Outermost loops through A for all columns
Related
I am trying to solve the following problem: "Write an algorithm to print all the ways of arranging eight queens on an 8x8 chess board so that none of them share the same row, column or diagonal (i.e. no two queens attack each other.)"
I am having trouble understanding why the author used Integer[] instead of the more common int[], for example in "Integer[] columns" and "ArrayList results" which are parameters to placeQueens. My hypothesis is that this is due to generics in Java, but I'm not entirely sure.
Code snippet below. Link to complete code at bottom of page.
public static int GRID_SIZE = 8;
/* Check if (row1, column1) is a valid spot for a queen by checking if there
* is a queen in the same column or diagonal. We don't need to check it for queens
* in the same row because the calling placeQueen only attempts to place one queen at
* a time. We know this row is empty.
*/
public static boolean checkValid(Integer[] columns, int row1, int column1) {
for (int row2 = 0; row2 < row1; row2++) {
int column2 = columns[row2];
/* Check if (row2, column2) invalidates (row1, column1) as a queen spot. */
/* Check if rows have a queen in the same column */
if (column1 == column2) {
return false;
}
/* Check diagonals: if the distance between the columns equals the distance
* between the rows, then they're in the same diagonal.
*/
int columnDistance = Math.abs(column2 - column1);
int rowDistance = row1 - row2; // row1 > row2, so no need to use absolute value
if (columnDistance == rowDistance) {
return false;
}
}
return true;
}
public static void placeQueens(int row, Integer[] columns, ArrayList<Integer[]> results) {
if (row == GRID_SIZE) { // Found valid placement
results.add(columns.clone());
} else {
for (int col = 0; col < GRID_SIZE; col++) {
if (checkValid(columns, row, col)) {
columns[row] = col; // Place queen
placeQueens(row + 1, columns, results);
}
}
}
}
Source for question/code: Cracking the Coding Interview. Link to complete code: https://github.com/gaylemcd/ctci/blob/master/java/Chapter%209/Question9_9/Question.java
In Java, Integer represents an object, while int is a primitive type. The Integer class supports more functions and can hold null values. In addition, ArrayList can only contain objects such as Integer.
ArrayList<int[]> results = new ArrayList<int[]>();
In the revised code above, int[] would still work because it is considered an object. However, the author may be seeking consistency or would need the extra functionality of the Integer object. It is a matter of the author's preference or ignorance.
You may think that the first line of the main (from the link you've provided):
ArrayList<Integer[]> results = new ArrayList<Integer[]>();
Must use Integer, but as comments suggest, it's not the case.
ArrayList<int[]> results = new ArrayList<int[]>();
Would also worked. So it's just the author's preference in that case.
I have a fundamental question about how arrays store data and how to properly put data into an array.
THIS PART ANSWERED
In this code the method spinWheel() is just calling an integer from 0-36.
for(cntr=0; cntr<99; cntr++)
{
spunNum=spinWheel();
all99Spun[0]=spunNum;
}
How do I adjust the array all99Spun[] so that the next time the loop executes it would put spunNum into all99Spun[1] and so forth?
Another question I have about arrays is how to check equality between 1 integer and all the integers stored in an array.
for example I have an array that stores all the red numbers of a roulette wheel.
int redNumbers[] = new int[] {1,3,5,7,9,12,14,16,18,19,21,23,25,27,30,32,34,36};
How would I check the equality of a number stored in the all99Spun array with that of the integers in the array of rednumbers?
Just change
all99Spun[0]=spunNum;
to
all99Spun[cntr]=spunNum;
To answer the second question, I think you just want to see if any one number from the spun array exists in the read array. If you want to check that just one number exists in the read array you can loop through until you find that number:
int num = all99Spun[0];
int index = -1;
for(int i = 0; i < redNumbers.length ; i++)
{
if(redNumbers[i] == num)
{
index = i;
break;
}
}
if at the end index does not equal -1, then the number was in the redNumbers array.
If you want to check it for the entire array:
for(int i = 0 ; i < all99Spun.length ; i++)
{
for(int j = 0; j < redNumbers.length; j++)
{
if(redNumbers[j] == all99Spun[i])
{
//doWork
}
}
}
Just change
all99Spun[0]=spunNum;
to
all99Spun[cntr]=spunNum;
Given the way I understand your first question, I think #Gregory's answer is right.
So I will try to answer your second question.
Another question I have about arrays is how to check equality between 1 integer and all the integers stored in an array.
There are 2 easy ways to see if an array of integers are equal.
Iterate through with a loop, keeping a reference to the previous number. The minute you find one that does not equal the previous one, you know they are not all equal.
Since you are using Java, you can add them all to a Set, which guarantees uniqueness. If they are all equal, then after adding them all to the set, the set should contain only 1 element.
Example of first:
for (int i = 0; previous = redNumbers[i]; i < redNumbers.length; i++) {
if (redNumbers[i] != previous) {
// they are not all equal.
}
previous = redNumbers[i];
}
Example of second:
Set<Integer> distinct = new TreeSet<>(Arrays.asList(redNumbers));
if (distinct.size() > 1) {
// they are not all equal.
}
Trying to compare the elements of an array. For instance, would like to return a boolean if array[0][0] was equal to array[0][1]. I figured seeing if two elements were not equal would be easier. So
boolean rowAlike = true;
for(int row = 0; row<size; row++)
{
for(int col = 0;col<size;col++)
{
nextNum = col + 1;
if(!square[row][col].equals(square[row][nextNum]))
rowAlike=false;
}
if(rowAlike)
System.out.println("All digits are the same in row " +row++);
Since arrays are reference variables I know that == will compare the memory locations rather than the values of those elements. I tried it they way above and also tried
Arrays.equals(square[row][col],(square[row][nextNum])
I either get a false false or a compiler error.
EDIT: the false false I receive is when using == I get a compiler error using .equals
ExploreMatrix.java:89: error: int cannot be dereferenced
And when using Arrays.equals
ExploreMatrix.java:89: error: no suitable method found for equals(int,int)
Primitives (such as int) are tested by values with == and/or != (as appropriate). You need to define the rowAlike in the loop body (or it won't reset on the next row). Accessing col + 1 when col == size - 1 will result in an ArrayIndexOutOfBounds. I suggest you start at 1 and then compare to the previous. Next, you can break in your loop when you first find a value that doesn't match. Finally, for display, you shouldn't modify the value of row (or you will skip a row). Putting it all together,
int[][] square = new int[size][size];
//
// ... Setup values in square ...
//
for (int row = 0; row < size; row++) {
boolean rowAlike = true;
for (int col = 1; col < size; col++) {
if (square[row][col - 1] != square[row][col]) {
rowAlike = false;
break;
}
}
if (rowAlike) {
System.out.printf("All digits are the same in row %d%n",
row + 1);
}
}
if(!square[row][col].equals(square[row][nextNum]))
The code above will work if your square is an array of String.
Unfortunately, you did not define square in your question.
Use == for comparing primitive types like int and .equals for comparing String
There are multiple issues in your code:
Most likely, an ArrayIndexOutOfBoundsException occurs (which is a
RuntimeException) here:
for(int col = 0;col<size;col++){
nextNum = col + 1;
if(!square[row][col].equals(square[row][nextNum]))
//...
}
In the last iteration, colwill be size-1, which means nextNumwill be equal to the arrays size. An array of size x has
indices 0to x-1.
You increment rowtwice (for-loop and SYSOUT)
I know that == will compare the memory locations
This does not apply for primitive types. According to your Exception, you try to compare int-values. Go for ==.
Check the JavaDoc of Arrays#equals() method.
I've been struggling to create a function to essentially find all the indices of duplicate elements in a multi-dimensional array(unsorted), in this case a 5x5 array, and then using the indices found changing the parallel elements in a score array. But only find duplicates within columns and not comparatively to the other columns in the array Here is what I've done so far, with research online. The main problem with this code is that it will find all the duplicate elements but not the originals. For example: if the array holds the elements:
{{"a","a","a"},{"b","b","b"},{"a","c","a"}}, then it should change the parallel score array to: {{0,1,0},{1,1,1},{0,1,0}}. But instead it only recognizes the last row and top the top row's duplicates.
Code:
public static void findDuplicates(String a[][])
{
System.out.println("*Duplicates*");
Set set = new HashSet();
for(int j = 0; j<a.length; j++)
{
for(int i=0; i < a[0].length; i++)
{
if(!set.contains(a[i][j]))
{
set.add(a[i][j]);
}
else
{
System.out.println("Duplicate string found at index " + i + "," + j);
scores[i][j] -= scores[i][j];
}
}
set = new HashSet();
}
}
I know my explanation is a bit complicated, but hopefully it is understandable enough. Thanks,
Jake.
Your logic is incorrect. Your outer loop is j and inner loop is i but you're doing:
set.add(a[i][j]);
It should be the other way around:
set.add(a[j][i]);
Technically you could get an out of bounds exception if the array isn't NxN. But you can state that as a precondition.
For some reason you're also setting to 0 with:
scores[i][j] -= scores[i][j];
Why not just:
scores[i][j] = 0;
But to find duplicates within columns:
public static void findDuplicates(String a[][]) {
for (int col=0; col<a[0].length; col++) {
Map<String, Integer> values = new HashMap<String, Integer>();
for (int row=0; row<a.length; row++) {
Integer current = values.put(a[row][col], row);
if (current != null) {
scores[row][col] = 0;
scores[current][col] = 0;
}
}
}
}
How does this work?
I've renamed the loop variables to row and col. There's no reason to use i and j when row and col are far more descriptive;
Like you I assume the input array is correct as a precondition. It can be NxM (rather than just NxN) however;
I use a Map to store the index of each value. Map.put() returns the old value if key is already in the Map. If that's the case you've found a duplicate;
The current (row,col) and (current,col) are set to 0. Why subtract the score from itself rather than simply setting to 0?
if the value "a" is found 3+ times in a column then scores[current][col] will be set to 0 more than once, which is unnecessary but not harmful and makes for simpler code.
I've declared the Map using generics. This is useful and advisable. It says the Map has String keys and Integer values, which saves some casting;
It also uses auto-boxing and auto-unboxing to convert an int (the loop variable) to and from the wrapper class Integer.
I'm trying to print how many rows contain subarrays (a, b, c) which satisfy a + b = c
int [][] matrix = {
{0,**5,2,7**,0,0},
{6,0,2, 1,-5,5},
{8,5,**1,1,2**,-2},
{3,-1,-5,-3,-4,-2}
};
this is the matrix in question it has only two sums so my program should print 2 , but somehow i miss something , the program should only print the rows that contain a sum of numbers not matter how many they are on a row
int [][] matrix = {
{0,5,2,7,9,0},
{6,0,2, 1,-5,5},
{8,5,1,1,2,-2},
{3,-1,-5,-3,-4,-2}
};
for example here we have 3 sums, but my program should print 2 anyway
public static int rowSumsOfThree(int [][] matrix) {
int count = 0 ;
if (matrix.length != 0 ) {
for (int i = 0 ; i < matrix.length ; i++) {
for (int j = 0 ; j < matrix[0].length-2 ; j++)
if (matrix[i][j] + matrix[i][j+1] == matrix[i][j+2]) {
count++;
break;
}
}}
return count;
}
this is my code so far , i know it's maybe some stupid mistake i make , if you can provide some explanation it is greatly appreciated , thank you all
Maybe my english is bad , I need to create a method that sums the elements within an array as
int [] matrix = {{2,3,4,7,8,3,2},
{1,23,4,2,2,}};
given this matrix , i need to sum them like this , first two elements = the third , second and third element = the fourth and so on , if the algorithm checks than it should return on how many rows it checks , first matrix should be 2 , second matrix should be 1 ; i hope i explained better
EDIT : Use of break solved my problem ! It will count only one sum per row , even if there are more per row , therefor count will be equal also to the numbers of rows. thank you for the help
As ari said, your return statement should be:
return count;
not
return rowIndex;
It's a very simple bug, consider deleting your question.