【问题标题】:Best way to remove duplicates from multidimensional array?从多维数组中删除重复项的最佳方法?
【发布时间】:2011-07-07 07:45:02
【问题描述】:

假设我有一个数组:

double[][] points = {{0.0, 0.0}, {1.0, 1.0}, {1.0, 1.0},  {2.0, 2.0}};

我想创建一个没有重复条目 {1.0, 1.0} 的新数组 - 最好的方法是什么?

附加信息:

  • 数组是排序的,但仅按第一个组件,所以有可能有

    {1.0, 2.0}, {1.0, 1.0}, {1.0, 2.0}
    

    这就是我获取数据的方式,我无法更改初始排序机制。

  • 二维是目前的极限,但数组可以有数千个点。

【问题讨论】:

  • 所以...愚蠢的答案是double[][] points2 = {{0.0, 0.0}, {1.0, 1.0}, {2.0, 2.0}}; 我敢肯定这不是你想要的!是否要过滤所有重复项?如果是这样,您是否保证数组已排序? ...请澄清。
  • 你试过暴力破解吗?
  • 你需要担心二维还是N维?
  • 您在哪些限制条件下运行?如果你有一个足够小的数组,你可以做一个双循环并比较每对元素。
  • @EdStaub:是的,这就是我想要的。制作a b b ca b c

标签: java multidimensional-array


【解决方案1】:

最简单的答案:成对比较数组的元素并删除重复项。这不会很好地扩展,但它可能不需要。

更复杂:查看类似radix sort 的内容。按子数组的第一个和第二个元素排序后,您可以遍历整个数组并删除重复项。这将更好地扩展,但它很容易被矫枉过正(取决于你的情况)。

最佳(可能):创建一组数组元素。穿过阵列;对于每个元素,检查它是否已经在集合中。如果是,请将其从阵列中删除。如果没有,请将其添加到集合中并继续。这可能是最好的方法,除非复制数组是空间问题。

【讨论】:

  • 我也在考虑 Set 方法,但我不明白如何实现它,因为 Set 让我高兴地添加 new double[] {1.0, 1.0} 两次。
  • @htorque:Java 的 set 实现中的 add 方法如果成功添加对象(即不重复)则返回 true,否则返回 false。
  • 我知道,但它两次返回 true
  • 除此之外,它实际上只会存储一个数据实例,因此您甚至不需要检查add 方法的结果。您可以将所有内容添加到集合中,然后从集合中请求一个数组。
  • 是的,double[] 类型不会覆盖 equals(),因此您正在比较引用。您将需要使用自定义 Comparator 或其他一些比较元素的方法。
【解决方案2】:

您不需要创建所有点的集合 - 只需要每个 X 的 Y 值,因为它们是在 X 上排序的。使用 HashSet 需要自动装箱每个值 - 在效率方面,请使用 TDoubleHashSet反而。这可能接近最佳状态 - 部分取决于重复的频率。

这与输入的顺序一样,但是当给定 X 值有多个 Y 值时,它们的输出顺序可能与输入不同。

double prevPoint[];
// If efficiency matters, use Trove TDoubleHashSet instead.
HashSet<Double> set;
ArrayList<double[]> buffer;

double[][] filter(double[][] points)
{
    prevPoint = new double[]{Double.NaN, Double.NaN};
    set = new HashSet<Double>();
    // Allocate space as if there were no duplicates.
    // Tweak if expecting lots of dupes.
    buffer = new ArrayList<double[]>(points.length);
    for ( double[] point : points )
    {
        if ( prevPoint[0] != point[0] )
        {
            emitSet();
            set.clear();

        }
        set.add(point[1]);
        prevPoint = point;
    }

    // output hashset
    emitSet();

    return buffer.toArray(new double[buffer.size()][2]);
}

private void emitSet()
{
    for ( double y : set )
    {
        // optimize out array create for common case of only 1 y with the same x.
        // get rid of this complexity if efficiency not needed.
        if ( y == prevPoint[1] )
        {
            buffer.add(prevPoint);
        }
        else
        {
            buffer.add(new double[] {prevPoint[0], y});
        }
    }
}

【讨论】:

    【解决方案3】:

    创建一组“数组”元素。 'array' 元素在包含相等元素时应返回相等的真值。

    【讨论】:

      【解决方案4】:
      【解决方案5】:

      您可以做的一件简单的事情是在向数组添加新元素之前进行检查。

      【讨论】:

      • 不是一个选项。我需要将副本保留在原始文件中,没有它们,只有一个功能可以工作 - 痛苦少得多。 ;)
      • 那太糟糕了。没有真正有效的方法来删除它们。您必须对数组进行排序,或者遍历一个包含 N 个元素的数组,每个元素 N 次。
      • 不能在用重复项填充一个数组时创建两个数组吗?你想要的没有重复的可以存储在一个集合中,你不必担心检查重复。
      猜你喜欢
      • 2013-05-10
      • 2019-07-31
      • 2016-10-10
      • 2018-07-26
      • 2020-08-03
      • 2014-05-26
      • 2012-12-14
      • 2021-02-16
      • 1970-01-01
      相关资源
      最近更新 更多