简体   繁体   中英

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(ie 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--;
                        }
                    }
                }
            }
        }

PS Is there any other way to do this, without iterating 4 for loops ?

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.

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.

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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM