【问题标题】:Comparing arrays in Java比较Java中的数组
【发布时间】:2011-08-19 17:50:30
【问题描述】:

我有 2 个整数数组,一个是原始数组,一个是根据原始数组修改的。 可以从原始元素中添加或删除元素以将其转换为修改后的元素。我的问题是,在修改后,我需要找出哪些元素是新的,哪些元素是相同的,哪些元素不存在于原始数组中。

给定数据:

arr1 = 3,2,1      //Original array
arr2 = 1,4,5      //Modified array by adding and/or removing elements

我需要类似的东西:

same = 1
removed = 2,3
added = 4,5

显然,我可以编写几个嵌套的 for 循环并找出它,但这太低效了。我想知道是否有更好或更有效的方法来做到这一点.. 我正在使用 Java。 This page 解决了类似的问题,但不确定我是否可以用它来解决我的问题。

任何帮助将不胜感激。

【问题讨论】:

  • 整数是否保证有序?数组中可以有重复项吗?整数有上限吗?
  • 对不起,我应该提到这一点。不,不保证订单。我将编辑帖子以使其清楚。
  • 1,2,33,2,1 一样吗?

标签: java arrays algorithm


【解决方案1】:

如果内存不是限制,我建议使用Set 进行此类操作。只需在两个Set 对象上调用适当的方法即可找到您需要的东西。当然,这假设您的元素中有独特的元素,如果没有,那么在报告内容时您只对独特的元素感兴趣。例如

public static void testSet() {
    final Set<Integer> first = new HashSet<Integer>(Arrays.asList(1, 2, 3));
    final Set<Integer> second = new HashSet<Integer>(Arrays.asList(1, 4, 5));

    Set<Integer> result = new HashSet<Integer>(first);
    result.retainAll(second);
    System.out.println("Similar: " + result);

    result = new HashSet<Integer>(first);
    result.removeAll(second);
    System.out.println("Removed: " + result);

    result = new HashSet<Integer>(second);
    result.removeAll(first);
    System.out.println("Newly added: " + result);
}
/*
OUTPUT:

Similar: [1]
Removed: [2, 3]
Newly added: [4, 5]
*/

【讨论】:

  • 你在说什么方法?我从未听说过进行这种比较的 Java 库方法。
  • removeAll 和 retainAll 是完成这项工作的方法。
  • 用示例 sn-p 更新帖子。
【解决方案2】:

您可以遍历每个数组一次,显然可以使用删除保存迭代,例如从数组后面循环。

int[] same
for (int i = arr1.length; i >= 0; i--)
{
    if(arr2.contains(i))
        same.add(i)
        arr1.remove(i)
}
for (int i = arr2.length; i >= 0; i--)
{
    if(same.contains(i))
        arr2.remove(i)
}

那么arr1将是删除列表,arr2将被添加,same将是相同的。

【讨论】:

  • 这是一个简单的解决方案。谢谢,我也在看下面的动态编程解决方案。
  • 是的,这是“空间复杂度”方面的简单解决方案。 contains 这里的检查是 O(n) 仅供参考,这正是 Set 解决方案试图处理的问题。
  • @Sanjay 同意,它不是最好的,但它很简单。
  • 对不起,如果这看起来像挑剔,但这究竟有多简单?这段代码大约有 12 行,仅用于查找相同的内容和其他内容。在大约 16 行中,我用示例代码完成了所有 3 件事!此外,使用这个解决方案真的没问题,恕我直言,Set 解决方案是 OP 在处理“大”集合时必须牢记的,当内存不是限制时。当然,YMMV :)
【解决方案3】:

如果没有重复,并且最大整数受到限制,并且成员密度适中(例如,1% 或更好),则将它们放入 BitSet。两个集合的“and”是“相同的”,A.andNot(B) 是 A 中的,B.andNot(A) 是 B 中的。如果整数的密度适中,则速度非常快。

如果整数是稀疏的,则对每个数组进行排序并串联起来。

【讨论】:

    【解决方案4】:

    您正在尝试计算两个数组之间的Levenshtein distance

    有一个简单的动态规划解决方案来计算这个(取自维基百科):

    int LevenshteinDistance(char s[1..m], char t[1..n])
    {
      // for all i and j, d[i,j] will hold the Levenshtein distance between
      // the first i characters of s and the first j characters of t;
      // note that d has (m+1)x(n+1) values
      declare int d[0..m, 0..n]
    
      for i from 0 to m
        d[i, 0] := i // the distance of any first string to an empty second string
      for j from 0 to n
        d[0, j] := j // the distance of any second string to an empty first string
    
      for j from 1 to n
      {
        for i from 1 to m
        {
          if s[i] = t[j] then  
            d[i, j] := d[i-1, j-1]       // no operation required
          else
            d[i, j] := minimum
                       (
                         d[i-1, j] + 1,  // a deletion
                         d[i, j-1] + 1,  // an insertion
                         d[i-1, j-1] + 1 // a substitution
                       )
        }
      }
    
      return d[m,n]
    }
    

    您可以轻松更改此代码以告诉您各个操作是什么。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多