I'm trying to develop an algorithm in Java, which, given two matrices (let's say a and b), returns true if at least one row is identical in a and b.
Here's my attempt of method:
public static boolean check_row(int a[][], int b[][]){
boolean check = false;
for(int i = 0; i < a.length; i++){
for(int j = 0; j < b[0].length; j++){
if(a[i][j] == b[i][j])
check = true;
}
}
return check;
}
And here's a simple main:
public static void main(String[] args){
int a[][] = {{1,2}, {3,4}};
int b[][] = {{1,2}, {7,8}};
System.out.println(check_row(a, b));
}
Here I get true because first row of both matrices is the same.
But if I change the matrices initialization to this:
int a[][] = {{1,2}, {3,4}};
int b[][] = {{5,6}, {1,2}};
I get false, even though the first row of a and the second row of b are identical.
How should I modify the method in order to get true in both cases?
Your condition is too simple... High level idea is, that for each row from a and b pick a row and then identify whether it is the same, so you need 3 loops...
code:
public class SameRowFinder {
public static void main(String[] args){
int a[][] = {{1,2},{3,4}};
int b[][] = {{1,2}, {7,8}};
System.out.println(hasSameRow(a, b));
int aa[][] = {{1,2},{3,4}};
int bb[][] = {{5,6}, {1,2}};
System.out.println(hasSameRow(aa, bb));
}
private static boolean hasSameRow(int[][] a, int[][] b) {
for (int i = 0; i < a.length; i++) {
for (int j = 0; j < b.length; j++) {
if (isSameRow(a[i], b[j])) {
System.out.printf("Same rows are %d and %d (0-based).%n", i, j);
return true;
}
}
}
return false;
}
private static boolean isSameRow(int[] row1, int[] row2) {
if (row1.length != row2.length) {
throw new IllegalArgumentException("rows with different length");
}
for (int i = 0; i < row2.length; i++) {
if (row1[i] != row2[i]) {
return false;
}
}
return true;
}
}
Also you do not need to write your own function for array compare, but use Arrays.equal(int[], int[]), but it will just hide 3rd loop. Method above throws runtime exception in case of different length of arrays. It's definitelly worth look at Arrays.equal(int[], int[]) implementation for some tips (check for equality + null checks).
You have an error in your 2nd loop.
Change:
for(int j = 0; j < b[0].length; j++)
to
for(int j = 0; j < b.length; j++){
Further, the issue is that you cannot compare the rows like you do it.
You have to check that the rows have the same length and finally compare the rows. You will need an additional for loop for comparing the rows.
This one will do the trick:
public static boolean check_row(int a[][], int b[][]){
boolean check = false;
for(int i = 0; i < a.length; i++){
for(int j = 0; j < b.length; j++){
if (compareRows(a[i], b[j]))
check = true;
}
}
return check;
}
private static boolean compareRows(int[] row1, int[] row2) {
if (row1.length == row2.length) {
for (int i = 0; i < row2.length; i++) {
if (row1[i] != row2[i]) {
return false;
}
}
return true;
}
return false;
}
public static void main(String[] args){
int a[][] = {{1,2},{3,4}};
int b[][] = {{5,6}, {1,2}};
System.out.println(check_row(a, b));
}
In the example provided by OP, the loop over rows in b matrix was missing.
When learning, the algorithm can be written as follows:
public static boolean check_row(int a[][], int b[][]) {
int row_size = a[0].length;
for (int i = 0; i < a.length; i++) {
b: for (int j = 0; j < b.length; j++) {
for (int k = 0; k < row_size; k++) {
if (a[i][k] != b[j][k])
continue b; // move to next row in 'b' matrix
}
return true; // all elements in row were equal if we reached this point
}
}
return false;
}
In real life it would probably look like this:
public static boolean check_row(int[][] a, int[][] b) {
return Arrays.stream(b)
.anyMatch(rowB -> Arrays.stream(a).anyMatch(rowA -> Arrays.equals(rowA, rowB)));
}
i hope this code can help you
public static boolean check_row(int a[][], int b[][])
{
boolean check = false;
for(int i = 0; i < a.length; i++)
{
for(int k = 0 ; k< b.length ; k++)
{
for(int j = 0 ; j<b[0].length ; j++)
{
if(a[i][j]!=b[k][j])
{
break;
}//if even one cell were not similar in both a and b break
else
{
if(j==b[0].length-1)
{
check = true;
}//if you haven't broken the loop yet and if j went till the end
}//else if they are equal
}//j to go through columns
if(check == true)
{
break;
}//for bringing down the time complexity
}//k to go through b rows
if(check == true)
{
break;
}//for bringing down the time complexity
}//i
return check;
}
Related
Given the following code:
public static int countSames(Object[] a) {
int count = 0;
for (int i = 0; i < a.length; i++) {
for (int k = 0; k < a.length; k++) {
if (a[i].equals(a[k]) && i != k) {
count += 1;
break; //Preventing from counting duplicate times, is there way to replace this?
}
}
}
return count;
}
I would like to know if there is a solution which doesn't use break statement since I've heard its bad practice.
But without the break this method returns 6 instead of wanted 3 for array {'x', 'x', 'x'}.
If you're trying to find the number of unique elements in the array try using this approach as it has only one loop and hence efficient.
private static int findNUmberOfUnique(String[] array) {
Set<String> set=new HashSet<>();
for(int i=0;i<array.length;i++){
if(!set.contains(array[i])){
set.add(array[i]);
}
}
return set.size();
}
Let me know if I did not understand your requirement clearly.
You can always use a flag instead of break:
public static int countSames(Object[] a) {
int count = 0;
for (int i = 0; i < a.length; i++) {
boolean found = false;
for (int k = 0; k < a.length && !found; k++) {
if (a[i].equals(a[k]) && i != k) {
count += 1;
found = true;
}
}
}
return count;
}
You can use a hashmap to find the same elements in an array and preventing duplicate counting.
class Solution {
public int[] intersection(int[] nums1, int[] nums2) {
HashSet<Integer>hs=new HashSet<Integer>();
for(int i:nums1)
hs.add(i);
HashSet<Integer>hs1=new HashSet<Integer>();
for(int j:nums2){
if(hs.contains(j)){
hs1.add(j);
}
}
int[] res=new int[hs1.size()];
int j=0;
for(int k:hs1)
res[j++]=k;
return res;
}
}
I need to create a method within my class to add two 2d arrays together. One is implemented as a parameter in the method, while the other is a class object. I need to make sure the arrays are the same size, and if so, add them together. I keep getting an Array Out of Bounds error. Whats wrong with my code?
// method to add matrices
public int[][] add(int[][] matrix) {
int addedMatrices[][] = new int[row][column];
if (userArray[row][column] == matrix[row][column]) {
for (int i = 0; i < row; ++i) {
for (int j = 0; j < column; ++j) {
addedMatrices[i][j] = matrix[i][j] + userArray[i][j];
System.out.println(addedMatrices[i][j]);
}
}
}
return addedMatrices;
}
if (userArray[row][column] == matrix[row][column]) is the problem.
Remember that arrays are zero-indexed so the elements are numbered from zero to row - 1. Trying to access row row is guaranteed to throw an ArrayIndexOutOfBoundsException because the last row is at index row - 1.
I'm not sure why you even have this line. If you change row to row - 1 and column to column - 1 then this line checks if the bottom-right values in the two matrices are the same. If they're not then the matrices will not be summed. Is that what you intended to do?
I think this is what you are trying to do :
public class Test {
static int row =3;
static int column =2;
static int[][] userArray = new int[][] {{1,1},{2,2},{3,3}};
public static void main(String[] args) {
add(new int[][] {{4,4},{5,5},{6,6}});
}
// method to add matrices
public static int[][] add(int[][] matrix) {
int addedMatrices[][] = new int[row][column];
//check arrays are of the same size
if ((userArray.length == matrix.length) && (userArray[0].length == matrix[0].length) ) {
for (int i = 0; i < row; ++i) {
for (int j = 0; j < column; ++j) {
addedMatrices[i][j] = matrix[i][j] + userArray[i][j];
//printout
if(j == (column -1)) {
for(int col = 0; col < column; col++) {
System.out.print(addedMatrices[i][col]+ " ");
}
}
System.out.println();
}
}
}
return addedMatrices;
}
}
or better:
public class Test {
static int[][] userArray = new int[][] {{1,1},{2,2},{3,3}, {4,4}};
public static void main(String[] args) {
add(new int[][] {{5,5},{6,6},{7,7},{8,8}});
}
// method to add matrices
public static int[][] add(int[][] matrix) {
//check arrays are of the same size
if ((userArray.length != matrix.length) || (userArray[0].length != matrix[0].length) ) {
System.out.println("Error: arrays are not of the same size");
return null;
}
int rows = userArray.length;
int cols = userArray[0].length;
int addedMatrices[][] = new int[rows][cols];
for (int i = 0; i < rows; ++i) {
for (int j = 0; j < cols; ++j) {
addedMatrices[i][j] = matrix[i][j] + userArray[i][j];
//printout
if(j == (cols -1)) {
for(int col = 0; col < cols; col++) {
System.out.print(addedMatrices[i][col]+ " ");
}
}
System.out.println();
}
}
return addedMatrices;
}
}
to make the print out more elegant you could change the for loop to :
for (int i = 0; i < rows; ++i) {
for (int j = 0; j < cols; ++j) {
addedMatrices[i][j] = matrix[i][j] + userArray[i][j];
}
System.out.println(Arrays.toString(addedMatrices[i]));
}
The line if (userArray[row][column] == matrix[row][column]) { should be replaced by a line to check if the dimensions of both matrices are the same (I guess that is what's intended). Assuming they are both rectangular arrays, and non empty:
public class MatrixAdder {
static public int[][] userArray = {{1,2},{3,4},{5,6}};
static public int[][] add(int[][] matrix) {
final int nb_rows1 = matrix.length; // nb rows in matrix
final int nb_cols1 = matrix[0].length; // nb columns in matrix
final int nb_rows2 = userArray.length; // nb rows in userArray
final int nb_cols2 = userArray[0].length; // nb columns in userArray
// this assumes A[0] exists, and A[0].length == A[1].length == ...
// both for matrix and userArray
int addedMatrices[][] = new int[nb_rows1][nb_rows1];
if ((nb_rows1==nb_rows2) && (nb_cols1==nb_cols2)) {
for (int i = 0; i < nb_rows1; ++i) {
for (int j = 0; j < nb_cols1; ++j) {
addedMatrices[i][j] = matrix[i][j] + userArray[i][j];
System.out.println(addedMatrices[i][j]);
}
}
}
return addedMatrices;
}
static public void main(String[] args)
{
int[][] mx1 = {{10,100},{20,200},{40,400}};
int [][] mx2 = add(mx1);
}
}
To be more robust, you could check that the dimensions of all sub-arrays are the same. You could also check if the matrix has zero dimension (otherwise array[0] will give an error).
If the dimensions are not the same, the returned matrix is filled with zeroes.
If this is not exactly what you need, it should give you enough hints.
if (userArray[row][column] == matrix[row][column]) {}
This is strange to me, I honestly don't know what the intentions are (Your just comparing the last element of each array).
I would do
if(addedMatrices.length == userArray.length && addedMatrices.length == matrix.length){}.
This is ugly but I don't know anything about userArray or matrix. I am presuming userArray is global. Also do j++ and i++, it has the same end result but it is more of the norm.
Hello I create a 2D array and i want to find the position from the first 2 in the array. And after to add the index in a new ArrayList. But this code doesn't work. Any idea for the problem?
import java.util.ArrayList;
class Test {
public static void main(String[] args) {
ArrayList<Integer> tableau = new ArrayList<Integer>();
int[][] tab = {
{1,1,1,1,1,1,2,1,1,2,1,1,1,2,1,2,1,1,1,1,1},
{1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1},
};
for (int i = 0; i < tab.length; i++) {
int j = tab[i].indexOf(2);
for (int k = j ; k < tab[i].length; k++) {
if (tab[i][j] == 2){
tableau.add(j);
}
}
}
for (Integer row : tableau) {
System.out.println("row = "+ Arrays.toString(tableau));
}
}
}
As others have mentioned, regular arrays do not have an indexOf method, meaning that you will get an error when you compile.
However, you can easily create your own method to use as a substitute.
private static int indexOf(int value, int[] array)
{
for (int i=0; i<array.length; i++)
{
if (array[i] == value)
return i;
}
return -1;
}
Then you can just replace this line:
int j = tab[i].indexOf(2);
With this one:
int j = indexOf(2, tab[i]);
i have an array of integers like this one :
A={1,1,4,4,4,1,1}
i want to count the each number once , for this example the awnser is 2 becuase i want to count 1 once and 4 once
i dont want to use sorting methods
i am unable to find a way to solve it using java.
i did this but it gives me 0
public static void main(String args[]) {
int a[] = { 1,1,4,4,4,4,1,1};
System.out.print(new Test4().uniques(a));
}
public int uniques(int[] a) {
int unique = 0;
int tempcount = 0;
for (int i = 0; i < a.length; i++) {
for (int j = 0; j < a.length; j++) {
if (a[i] == a[j]) {
tempcount++;
}
}
if (tempcount <= 2) {
unique=a[i];
}
tempcount = 0;
}
return unique;
}
the purpose of the question is to understand the logic of it but not solving it using ready methods or classes
This one should work. I guess this might be not the most elegant way, but it is pretty straightforward and uses only simple arrays. Method returns number of digits from array, but without counting duplicates - and this I believe is your goal.
public int uniques(int[] a) {
int tempArray[] = new int[a.length];
boolean duplicate = false;
int index = 0;
int digitsAdded = 0;
for (int i = 0; i < a.length; i++) {
for (int j = 0; j < tempArray.length; j++) {
if (a[i] == tempArray[j]) {
duplicate = true;
}
}
if(!duplicate) {
tempArray[index] = a[i];
index++;
digitsAdded++;
}
duplicate = false;
}
//this loop is needed if you have '0' in your input array - when creating temp
//array it is filled with 0s and then any 0 in input is treated as a duplicate
//again - not most elegant solution, maybe I will find better later...
for(int i = 0; i < a.length; i++) {
if(a[i] == 0) {
digitsAdded++;
break;
}
}
return digitsAdded;
}
Okay first of all in your solution you are returning the int unique, that you are setting as the value that is unique a[i]. So it would only return 1 or 4 in your example.
Next, about an actual solution. You need to check if you have already seen that number. What you need to check is that for every number in the array is only appears in front of your position and not before. You can do this using this code below.
public int uniques(int[] a) {
int unique = 1;
boolean seen = false;
for (int i = 1; i < a.length; i++) {
for (int j = 0; j < i; j++) {
if (a[i] == a[j]) {
seen = true;
}
}
if (!seen) {
unique++;
}
seen = false;
}
return unique;
}
In this code you are iterating over the number you have seen and comparing to the number you are checking (a[i]). You know that for it to be unique you cant have seen it before.
I see two possible solutions:
using set
public int unique(int[] a) {
Set<Integer> set = new HashSet<>();
for (int i : a) {
set.add(i);
}
return set.size();
}
using quick sort
public int unique(int[] a) {
Arrays.sort(a);
int cnt = 1;
int example = a[0];
for (int i = 1; i < a.length; i++) {
if (example != a[i]) {
cnt++;
example = a[i];
}
}
return cnt;
}
My performance tests say that second solution is faster ~ 30%.
if restricted to only arrays, consider trying this:
Lets Take a temporary array of the same size of orignal array, where we store each unique letter and suppose a is your orignal array,
int[] tempArray= new int[a.length];
int tempArraycounter = 0;
bool isUnique = true;
for (int i = 0; i < a.length; i++)
{
isUnique = true;
for (int j = 0; j < tempArray.length; j++)
{
if(tempArray[j] == a[i])
isUnique = false;
}
if(isUnique)
{
tempArray[tempArraycounter] = a[i];
tempArraycounter++;
isUnique = false;
}
}
now tempArraycounter will be your answer ;)
Try Following code:
int test[]={1,1,4,4,4,1,1};
Set<Integer> set=new LinkedHashSet<Integer>();
for(int i=0;i<test.length;i++){
set.add(test[i]);
}
System.out.println(set);
Output :
[1, 4]
At the end set would contain unique integers.
I need some help from the experts. I've got a task to find 2 duplicate elements in a 2d array and print out their indexes. Here's the code i've made. It creates a 2d array, then fill it manually from the keyboard. But now i have some problems with the method that finds and prints the duplicates. It prints FALSE if there are no duplicates, and TRUE if there are some. But I can't make it print out ALL the duplicates and its indexes. Please help me with this. Best regards
import java.io.*;
import java.util.HashSet;
import java.util.Set;
import static java.lang.System.out;
public class Main {
public static void main(String[] args)
throws NumberFormatException, IOException {
BufferedReader reader = new BufferedReader
(new InputStreamReader (System.in));
out.println("Введите размерность массива n:");
int n = Integer.parseInt(reader.readLine());
out.println("Введите размерность массива m:");
int m = Integer.parseInt(reader.readLine());
int [][] a = new int [n][m];
out.println("Введите числа массива :");
int i,j;
for (i = 0; i < a.length; i++) {
for (j = 0; j < a[i].length; j++) {
a[i][j] = Integer.parseInt(reader.readLine());
}
}
out.println("Введенный массив : ");
for (i = 0; i < a.length; i++, out.println()) {
for (j = 0; j < a[i].length; j++) {
out.printf(" %4d", a[i][j]);
}
}
out.println(extra(a));
}
private static boolean extra(int[][] data) {
Set<Integer> set = new HashSet<Integer>();
for (int i = 0; i < data.length; i++) {
for (int j = 0; j < data[i].length; j++) {
if (set.contains(data[i][j])) {
out.printf("[%d][%d] - %d\n", i, j, data[i][j]);
return true;
} else {
set.add(data[i][j]);
}
}
}
return false;
}
}
A general method for determining if any item in a collection satisfies a condition, while also processing every item, is:
boolean conditionSatisfied = false;
for each item in collection {
if item satisfies condition {
process item;
conditionSatisfied = true;
}
}
return conditionSatisfied;
I changed your method and used one boolean variable found..This will work
private static boolean extra(int[][] data) {
boolean found = false;
Set<Integer> set = new HashSet<Integer>();
for (int i = 0; i < data.length; i++) {
for (int j = 0; j < data[i].length; j++) {
if (set.contains(data[i][j])) {
out.printf("[%d][%d] - %d\n", i, j, data[i][j]);
found = true;
} else {
set.add(data[i][j]);
}
}
}
return found;
}