Mr.Bhanushali
Mr.Bhanushali

Reputation: 126

Remove repeating values from 2d array

I have a 2d array like this.

int[,] arr = new int[3,5]{
             {1,2,3,4,5},
             {10,22,53,4,35},
             {1,12,13,45,51}};

Now i want to remove all the repeating values keeping order intact(i.e. after deleting the value index of other elements should not change)

Expected output is :

1  2  3  4  5
10 22 53 0  0
0  12 13 45 51 

Note: repeating values can be replaced with 0.

This is my attempt. can anyone please tell me what am i doing wrong.

 for (int i = 0; i < 3; i++)
        {
            for (int j = 0; j < 5; j++)
            {
                int a = matrix[i, j];
                int flag = 1;
                for (int k = 0; k < 3; k++)
                {
                    for (int l = 0; l < 5; l++)
                    {
                        if (a == matrix[k, l] && flag == 0)
                        {
                            matrix[k, l] = 0;
                        }
                        else if (a == matrix[k, l] && flag != 0)
                        {
                            flag--;
                        }
                    }
                }
            }
        }

P.S. Is there any other way to do this, without iterating 4 for loops ?

Upvotes: 1

Views: 125

Answers (4)

Hans Kesting
Hans Kesting

Reputation: 39329

My attempt:

int[,] arr = new int[3, 5]{
             {1,2,3,4,5},
             {10,22,53,4,35},
             {1,12,13,45,51}};

var rowsize = arr.GetLength(1);
var colsize = arr.GetLength(0);
var size = rowsize * colsize;

// index = row*rowlength + col
for (int idx1 = 0; idx1 < size; idx1++)
{
    var col = idx1 % rowsize;
    var row = idx1 / rowsize;
    var value = arr[row, col];
    if (value == 0) continue; // ignore 0's

    for (int idx2 = idx1 + 1; idx2 < size; idx2++)
    {
        var col2 = idx2 % rowsize;
        var row2 = idx2 / rowsize;
        if (arr[row2, col2] == value)
        {
            arr[row2, col2] = 0;
        }
    }
}
  • Treat the two-dimensional array as a single-dimensional one. That saves two loops
  • Walk through the entire array, noting the value there
  • Walk through the rest of the array (skipping the part you already had), checking for the noted value and setting to 0 is found
  • Use GetLength to avoid hardcoding the size of the array.

Upvotes: 1

juharr
juharr

Reputation: 32296

I suggest using a HashSet to keep track of the numbers you've already seen

var seen = new HasSet<int>();
for (int i = 0; i < matrix.GetLength(0); i++)
{
    for (int j = 0; j < matrix.GetLength(1); j++)
    {
        if(!seen.Add(matrix[i,j]))
        {
            matrix[i,j] = 0;
        }
    }
}

This works because HashSet<T>.Add returns false if the value is already in the hash set.

Also notice the use of GetLength instead of hard coding the length. This will make the code more reusable since you don't need to change it to make it work with an array of a different size.

Upvotes: 4

Schidu Luca
Schidu Luca

Reputation: 3947

Your method is not very efficient. You can try to solve this problem using HashSet. The idea is to go through the matrix, for every cell you have two conditions :

  1. Value is present in Set, in this case set matrix[i, j] to 0
  2. Valus is not present in Set, in this case add it to the Set

Upvotes: 0

Samvel Petrosov
Samvel Petrosov

Reputation: 7706

Here is example how you can implement this in more developer friendly mode:

static void Main(string[] args)
{
    int[,] arr = new int[3, 5]{
     {1,2,3,4,5},
     {10,22,53,4,35},
     {1,12,13,45,51}};

    int[,] newArray = new int[arr.GetLength(0), arr.GetLength(1)];
    for (int i = 0; i < arr.GetLength(0); i++)
    {
        for (int j = 0; j < arr.GetLength(1); j++)
        {
            if (!ArrayHasValue(newArray, arr[i, j]))
            {
                newArray[i, j] = arr[i, j];
            }
            else
            {
                newArray[i, j] = 0;
            }
        }
    }
    for (int i = 0; i < newArray.GetLength(0); i++)
    {
        for (int j = 0; j < newArray.GetLength(1); j++)
        {
            Console.Write(newArray[i, j]+" ");
        }
        Console.WriteLine();
    }
}

public static bool ArrayHasValue<T>(T [,] arr, T value)
{
    for (int i = 0; i < arr.GetLength(0); i++)
    {
        for (int j = 0; j < arr.GetLength(1); j++)
        {
            if (arr[i,j].Equals(value))
                return true;
        }
    }
    return false;
}

Off course the implemention of ArrayHasValue is not the best one and needs more validation in case if you use not int arrays.

Upvotes: 3

Related Questions