【问题标题】:Multidimensional array manipulation - Java多维数组操作 - Java
【发布时间】:2009-07-28 18:13:27
【问题描述】:

我有一系列数组,我从中提取数据并最终生成一个包含我想要的信息的最终数组。最终的数组是二维的,由大量一维数组组成,每个数组最多包含 3 个条目。

int[][] realOcc = new int[result.length][3];

数组保存数据的方式如下:第一个“单元格”保存名称,第二个“单元格”保存区域 ID,第三个保存出现次数 - 一个 int 值,告诉我该名称在该特定区域 ID 中出现了多少次.

使用冒泡排序算法根据名称对数组进行排序后,我自然会看到许多我不想出现的条目。例如,假设某个名称在特定区域 ID 中出现 3 次。此名称的数组条目如下所示:

Name1 regionID17 1
Name1 regionID17 2
Name1 regionID17 3
...
Name156 regionID1 1
Name168 regionID99 1
...

我想要做的是摆脱所有多余的条目,如对应于相同名称和 regID 的条目,并且只保留特定区域中每个名称的最大出现次数。因此,以上面的例子为例,我在操作数组后希望看到的是:

Name1 regionID17 3
...
Name156 regionID1 1
Name168 regionID99 1
...

任何想法都将不胜感激,因为我非常难过。请记住,由于我提取的数据数量很大,我还需要保持我的代码高效。

【问题讨论】:

    标签: java arrays data-structures


    【解决方案1】:

    我同意马里奥的观点,你不应该在这里使用数组结构。您正在使用冒泡排序这一事实表明您正在学习某种介绍性编程课程,因此您可能不知道 ArrayLists、HashSets、.equals() 方法等,但是这才是你真正想做的。使用自定义 .equals() 方法创建自定义对象 - 类似于:

    public class Record{
      String name;
      String region;
    
      public boolean equals(Object o){
        Record r = (Record)o;
        return name.equals(r.name) && region.equals(r.region);
      }
    
      public int hashCode(){
        return name.hashCode()+region.hashCode();
      }
    }
    

    然后您可以使用HashMap<Record, Integer> 检查集合中是否已存在记录 - 如果存在,则将 count(地图的值)增加 1,否则添加它。

    如果您希望所有内容按特定顺序排序,您可以定义自定义 .compareTo() 方法并使用 TreeMap,或者,如果您希望所有内容按插入顺序排列,请使用 LinkedHashSet<Record> 保留该顺序。

    【讨论】:

    • 不要忘记实现 hashCode 否则这个方法将不起作用,因为 HashSet 不会正确找到已经插入的对象。另外,对于这样的事情,我会使用 HashMap;记录只有名称和区域(否则与您的答案相同),而整数是计数。
    • 谢谢,是的,hashCode 绝对重要。
    • 非常感谢您的回答,它把我推向了正确的方向。
    【解决方案2】:

    您真正应该研究的是使用ArrayList 类来保存这些“项目”。

    您还应该创建一个特定的类来保存这些数据。

    您的自定义类应如下所示:

    class Entry implements Comparable<Entry> {
        private String name, region;
        private int occuranceCount;
    
        public Entry(String nameP, regionP, occurCountP){
            name = nameP;
            region = regionP;
            occuranceCount = occurCountP;
        }
    
        // Getters
    
        public int compareTo(Entry other){
            return name.compareTo(other.name);
        }
    
        // Equals and hashcode
    }
    

    然后您可以将这些对象放入ArrayList&lt;Entry&gt; 并使用Collections.sort(),这将比冒泡排序快得多。

    排序后,您可以使用ArrayList.remove() 循环并删除重复条目。

    【讨论】:

    • 既然可以使用某种哈希数据结构,为什么还要使用 ArrayList 并进行第二次迭代?
    • 好吧,也许他/她想要对数据进行某种排序。
    • 我知道一个集合可以解决很多问题,但它对元素也没有顺序感。
    • 一个 TreeMap 然后将允许您定义自定义排序。不过,从问题的声音来看,排序只是为了识别重复项并删除它们。
    • 你可能是对的。我想我是在假设他希望他的代码尽可能与现在相似。
    【解决方案3】:

    想到一个问题:为什么要使用数组?我认为最好使用 Set 对象来保存结果,然后创建一个具有三个字段的 Result 对象:一个用于名称,一个用于区域,一个用于计数。如果重写 equals 和 hash 方法以仅考虑区域和名称,那么您的集合中将没有重复项,您可以使用它来跟踪这些结果对象。

    实现相同的另一种方法是拥有一个 Map,其中键是名称 + 区域,值是计数。这也将使实施变得简单,并确保您没有重复。

    【讨论】:

      【解决方案4】:

      听起来像 Hashtable 或 Map 可能很有用。您可以通过原始数据进行一次传递,并使用 Map 来查找名称,如果尚未看到则添加它,或者检查新条目是否超过了它的值(如果超过)。这不需要提前排序;你可以事后排序,节省大量时间:-)

      【讨论】:

      • 虽然在技术上没有被弃用,但如果你能帮助它,你不想使用Hashtable,HashMap是正确的用法。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-21
      • 2011-05-06
      • 2020-01-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多