简体   繁体   English

从2D数组中删除重复值

[英]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. 注意:重复值可以替换为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 ? PS是否有其他方法可以执行此操作,而无需迭代4个for循环?

I suggest using a HashSet to keep track of the numbers you've already seen 我建议使用HashSet来跟踪您已经看到的数字

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. 之所以HashSet<T>.Add是因为HashSet<T>.Add如果该值已经在哈希集中,则返回false

Also notice the use of GetLength instead of hard coding the length. 还要注意使用GetLength而不是对长度进行硬编码。 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. 当然,实现ArrayHasValue并不是最好的方法,如果您不使用int数组,则需要更多的验证。

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 遍历数组的其余部分 (跳过您已有的部分),检查记下的值并将其设置为0
  • Use GetLength to avoid hardcoding the size of the array. 使用GetLength可以避免对数组的大小进行硬编码。

Your method is not very efficient. 您的方法不是很有效。 You can try to solve this problem using HashSet . 您可以尝试使用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 Set中存在值,在这种情况下,将matrix[i, j]0
  2. Valus is not present in Set, in this case add it to the Set Set中不存在Valus,在这种情况下,请将其添加到Set中

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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