2011-08-19 19 views
1

我很难理解如何在该算法中复制数组。我很好的代码,直到我到下面显示的第12行。这段代码来自我正在学习的一本书。 我只是想了解的副本是如何在每场比赛进行帮助理解使用arraycopy删除重复元素的java算法

写了一些数值来模拟一个场景

a = [10,4,6,10,5,2] 

a[0] = a[3] MATCH occurs when j=3 

arraycopy(a, 4, a, 3, (5-3)) // Variable values substituted into arraycopy. (pretty sure they're correct)    

System.arraycopy(a, j+1, a, 0, n-j); // Line 12 

整个代码:

int n = a.length; 

    if (n < 2){ 
     System.out.println("no duplicates"); 

    } 

    for (int i = 0; i< n-1; i++) 
     for (int j = i + 1; j < n; j++) 
      if(a[i] == a[j]){ 
       --n;      
       System.arraycopy(a, j+1, a, 0, n-j); // Line 12 
       --j;      


       System.out.println(); 
      } 
    int[] aa = new int[n]; 
    System.arraycopy(a, 0, aa, 0, n); 

只是为了记录我理解第二个arraycopy语句,因为它只是简单地复制到数组aa中。

我知道在SO上有很多阵列问题,但是我遇到的问题没有回答这个问题,因为我需要逐步了解复制的匹配方式。

无论如何感谢提前家伙。

+0

该算法应该做什么? – Kal

+0

它应该从数组中删除重复的数字 –

回答

3

我很确定算法中存在一个错误,因为第一个数组副本会覆盖数组前面的好数据。我认为该行应该是:

System.arraycopy(a, j+1, a, j, n-j); // Line 12 

这会将数组的末尾移到一个,只覆盖刚刚找到的一个副本。

现在,它的工作原理是这样的:

Before copy: 
i   j  n 
[1, 2, 3, 4, 1, 5, 6] 
       \/
       n-j 

After copy: 
i  j  n 
[5, 6, 3, 4, 1, 5, 6] 

显然是错误的。现在有更多重复比我们开始时!

与更新的行,它看起来像这样:

After copy: 
i  j  n 
[1, 2, 3, 4, 5, 6, 6] 

好多了。重复的1消失了。

作为一个附加说明,这是一个非常可怕的方法来消除数组中的重复。 所有重复的数组将执行(n *(n-1)/ 2)元素副本,这是很荒唐的。删除阵列的标准简单方法通常是将每个元素添加到HashSet,然后将该集的内容迭代到新阵列中。

+0

你好,你的权利。我正要向@kal发表评论,询问我是否可以对进入我的arraycopy方法的参数得到第二意见,因为我觉得你说“好数据被覆盖”。然后SO冻结在我身上。非常感谢你diev。我花了很长时间试图让它在我的脑海中语义上嘀嗒。 –

+0

很高兴能帮到你!如果您有兴趣,我在回答中添加了一个快速笔记,提供了更好地从数组中删除重复项的方法。 – dlev

+0

hey @diev。只是看看你的最后一个'复制'解释,在数组中仍然包含重复。它看起来像一个无辜的错字。 –