Repeated elements in a matrix

Asked

Viewed 2,182 times

3

I’m trying to make an algorithm that finds repeated elements in some matrix but I don’t know how. The algorithm should not check the repetition only in the rows or columns, but in the whole matrix (this seems to me to be the most complicated).

Could someone give a hint on how to implement this?

  • Do you already have some code of your attempts? If yes, could you share with us?

  • I don’t. I couldn’t think of any way for each element to be compared with everyone else in the matrix. The only thing I thought was to order the rows and columns in ascending order, then if you have repeated element they will be in consecutive positions and then you could do a check of type x == x+1. But I couldn’t implement it like that and I thought there was some simpler way.

  • Some of these answers answered him?

2 answers

1

Solution given in similar question on another web site (Soen) Finding repeats in a 2D array

/* package whatever; // don't place package name! */

import java.util.*;
import java.lang.*;
import java.io.*;

class Ideone
{
    public static void main (String[] args) throws java.lang.Exception
    {
        int[][] ia = new int[3][3];
        ia[0][0] = 1;
        ia[0][2] = 1;
        ia[0][2] = 1;
        ia[1][0] = 4;
        ia[1][3] = 4;
        ia[1][2] = 2;
        ia[2][0] = 5;
        ia[2][4] = 6;
        ia[2][2] = 7;
        findRepeats(ia, ia.length*ia[0].length);
    }

    public static void findRepeats(int [][] num, int size)
{
    int findNum;
    int total = 1, row = 0, col = 0;
    int [] check = new int[size];
    while(row < num.length && col < num[0].length)
    {
        //Set to number
        findNum = num[row][col];
      //Cycle array to set next number
        if(col < num[0].length-1)
            col++;
        else
        {
            row++;      //Go to next row if no more columns
            col = 0;    //Reset column number
        }
        //Loop through whole array to find repeats
        for(int i = row; i < num.length; i++)
        {
            for(int j = col; j < num[i].length; j++)
            {
                if(num[i][j] == findNum) {
                    total++;
                     //Cycle array to set next number
                      if(col < num[0].length-1)
                          col++;
                      else
                      {
                           row++;      //Go to next row if no more columns
                           col = 0;    //Reset column number
                      }
                      if(row < num.length - 1 && col < num[0].length -1)
                         num[i][j] = num[row][col];
                }
            }
        }


        //Display total repeats
        System.out.println("Number " + findNum + " appears " + total + " times.");
        total = 1;
    }
}
}

Functioning in the ideone

  • truth, I will update the reply.

1

To traverse an array you need a for within a for, So a possible solution is to go through the matrix and compare each element by going through the matrix again. So you’ll have 4 fornested s, the outer two of which are traversing the matrix for the first time, and the inner two are taking the element of the matrix’s external iteration and comparing the element of the internal iteration.

To increase the performance of your comparison, the two forMore internal s do not need to start from the element [0][0], iteration can start from the current element of the most external iteration. By finding a repeated element you store this value in a ArrayList and continues the most external iteration.

Thus:

import java.util.ArrayList;
import java.util.List;

public class Matriz {
    public static void main(String[] args) {
        int[][] matriz = new int[][]{
                {1,2,3,4},
                {3,4,5,6},
                {6,7,8,9}};
        List<Integer> repetidos = new ArrayList<Integer>();

        //percorre a matriz, elemento por elemento
        for(int i=0; i<matriz.length; i++) {
            proximoElemento:
            for(int j=0; j<matriz[i].length; j++) {
                //caso elemento já foi marcado como repetido
                //continua para a próxima iteração
                if(repetidos.contains(matriz[i][j])) continue proximoElemento;

                //percorre novamente a matriz, elemento por elemento
                //começando do elemento atual da iteração mais externa 
                for(int i2=i; i2<matriz.length; i2++) {
                    for(int j2=0; j2<matriz[i2].length; j2++) {
                        //não se compara com ele mesmo
                        if(i==i2 && j==j2) break;
                        //achamos um repetido, armazena e 
                        //continua para a próxima iteração 
                        if(matriz[i][j] == matriz[i2][j2]) {
                            repetidos.add(matriz[i][j]);
                            continue proximoElemento;
                        }
                    }
                }
            }
        }

        //exibe os elementos encontrados repetidos ao menos uma vez
        for(int r: repetidos) {
            System.out.println(r);
        }
    }
}

Upshot:

3
4
6

Example in Ideone

  • I didn’t understand why I2 would be initialized as i. If it were initialized as 0 the algorithm would work as well, right?

  • @Certain chittolina would also work, but it’s an optimization that I’ve done so that the forinternal s only traverse the elements that have not yet been traversed by forexternal s. This results in a smaller number of iterations. For a tiny example like what I wrote doesn’t make much difference, but since I don’t know how many elements your matrix has I preferred to optimize (at least a little) my code.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.