繁体   English   中英

从2D数组中删除重复值

[英]Remove repeating values from 2d array

我有这样的二维数组。

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

现在,我想删除所有重复的值,保持顺序完整(即删除其他元素的值索引后不应更改)

预期输出为:

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

注意:重复值可以替换为0。

这是我的尝试。 谁能告诉我我在做什么错。

 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是否有其他方法可以执行此操作,而无需迭代4个for循环?

我建议使用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;
        }
    }
}

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

还要注意使用GetLength而不是对长度进行硬编码。 这将使代码更可重用,因为您无需更改代码即可使其与其他大小的数组一起使用。

下面是示例,您如何以对开发人员更友好的方式实现此目标:

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

当然,实现ArrayHasValue并不是最好的方法,如果您不使用int数组,则需要更多的验证。

我的尝试:

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;
        }
    }
}
  • 将二维数组视为一维数组。 这样可以节省两个循环
  • 遍历整个数组,注意那里的值
  • 遍历数组的其余部分 (跳过您已有的部分),检查记下的值并将其设置为0
  • 使用GetLength可以避免对数组的大小进行硬编码。

您的方法不是很有效。 您可以尝试使用HashSet解决此问题。 想法是遍历矩阵,对于每个单元格,您都有两个条件:

  1. Set中存在值,在这种情况下,将matrix[i, j]0
  2. Set中不存在Valus,在这种情况下,请将其添加到Set中

暂无
暂无

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

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