簡體   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