2017-05-03 61 views
1

我有這樣的2d數組。從二維數組中刪除重複值

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

P.S.有沒有其他的方式來做到這一點,而不是迭代4循環?

+0

你得到了什麼輸出? –

+0

某些值不會被刪除 –

+0

@Mr。Bhanushali你有矩陣3x5,但初始化它與5x5正確的排隊請 –

回答

4

我建議使用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返回false如果值已經在散列集中。

另請注意,使用GetLength而不是硬編碼長度。這將使代碼更加可重用,因爲您不需要更改它以使其可以處理不同大小的數組。

+0

請'matrix.GetLength(0);'而不是幻數'3'和'matrix.GetLength(1)'而不是'5'。 –

+1

@DmitryBychenko我同意,但我只是試圖展示如何更新現有的代碼來使用'HashSet'。幻數看起來像是一個單獨的問題,但我會「修復」它。 – juharr

3

這裏是例如如何在更多的開發者友好的方式實現這一點:

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的FPGA實現是不是最好的,需要更多的驗證的情況下,如果你使用的不是int數組。

0

你的方法效率不高。您可以嘗試使用HashSet來解決此問題。我們的想法是要經過矩陣,爲每一個細胞,你有兩個條件:

  1. 值存在於集,在這種情況下設置matrix[i, j]0
  2. 衣被合計不存在於集,在這種情況下,加它設置
+0

其實你只是加了它,結果會告訴你它是否已經在集合中。 – juharr

1

我嘗試:

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來避免硬編碼數組的大小。
+0

你可以使用'foreach'作爲內部循環。同樣,'arr.Length'將是數組中所有維度的項目總數。 – juharr

+0

@juharr - 你不想抹去原來的價值 –

+0

沒關係,我明白你現在在做什麼。 – juharr