【问题标题】:How to find multiples of the same integer in an arraylist?如何在arraylist中找到相同整数的倍数?
【发布时间】:2011-02-14 00:51:26
【问题描述】:

我的问题如下。我有一个整数数组列表。数组列表包含 5 个整数,例如 [5,5,3,3,9] 或 [2,2,2,2,7]。许多数组列表都有重复的值,我不确定如何计算每个值存在多少。

问题是如何在数组列表中找到重复值并计算该特定重复值的数量。在第一个示例 [5,5,3,3,9] 中,有 2 个 5 和 2 个 3。 [2,2,2,2,7] 的第二个例子只有 4 个 2。我希望找到的结果信息是是否有任何重复项,其中有多少个以及已重复的特定整数。

我不太清楚如何在 java 中做到这一点。

任何帮助将不胜感激。谢谢。

【问题讨论】:

    标签: java loops integer arraylist


    【解决方案1】:

    两种算法浮现在脑海中。

    排序 (Collections.sort)。然后遍历轻松找到骗子。

    通过将计数保持在Map<Integer,Integer>(或Map<Integer,AtomicInteger> 用于可变计数)中进行迭代。这样有点难看。

    无论哪种方式,编码都应该是一个有启发性的练习。我建议两者都做,然后进行比较。

    【讨论】:

    • #2 的变体:迭代一次以使用(在示例中)[5, 0], [3, 0], [9, 0] 填充地图;然后第二次通过以获得计数。我发现这个逻辑比在每个点检查值是否已经是地图的键更简单。
    • 那条评论听起来很像。我以前从未使用过地图,所以不知道该怎么做
    • 这是我去“为什么不能像 Python 一样”的时候之一...... defaultdict 在这里可以完美地工作。 :)
    • @Dan map.put(key, value); 插入一个值。 Integer value = map.get(key); 检索一个值(如果键未映射,则为 null。使用 Map<Integer,Integer> map = new HashMap<Integer,Integer>(); 创建。这就是您所需要的。@Dav 也许在 Google 的收藏中有些东西(或者也许不值得考虑(在 Java 中))。ConcurrentMap.putIfAbsent 会让事情变得更干净,如果更晦涩的话。
    【解决方案2】:

    使用Hashmap集合除了数组列表所在

    • Hashmap 键是唯一的数组 int 值和
    • 键的 Hashmap 值是遇到的每个值的计数。

    遍历您的数组列表,将这些值收集到哈希图中,当先前的键不存在时添加一个新项目,并将已经存在的键的值增加 1。然后遍历 Hashmap 并打印出任何值大于 1 的键。

    【讨论】:

      【解决方案3】:

      您可以通过List 并将它们放入带有计数的Map 中。然后很容易找出哪个是重复的。

      【讨论】:

      • 我以前从未在 java 中使用过 Maps,知道我会怎么做吗?干杯。
      【解决方案4】:

      为了更清晰地抽象出您正在做的事情,您可以使用来自guava/google-collectionsMultiset 数据结构。你甚至可能会发现你宁愿使用它而不是List,这取决于你用它做什么(如果你不需要列表的确定性排序)。你会这样使用它:

      Multiset<Integer> multiset = HashMultiset.create(list);
      int count = multiset.count(3); // gets the number of 3s that were in the list
      

      就上述内容而言,这几乎完全等同于根据您的列表构建Map&lt;Integer,AtomicInteger&gt; 的建议。

      【讨论】:

        【解决方案5】:

        这是我在 cmets 中对@Tom 的回答所描述的具体实现和测试:

        package playground.tests;
        
        import java.util.HashMap;
        import java.util.HashSet;
        import java.util.Map;
        import java.util.concurrent.atomic.AtomicInteger;
        
        import junit.framework.TestCase;
        
        public class DupeCounterTest extends TestCase {
        
            public void testCountDupes() throws Exception {
                int[] array = new int[] { 5, 5, 3, 3, 9 };
                assertEquals("{3=2, 5=2}", countDupes(array).toString());
            }
        
            private Map<Integer, AtomicInteger> countDupes(int[] array) {
                Map<Integer, AtomicInteger> map = new HashMap<Integer, AtomicInteger>();
                // first create an entry in the map for every value in the array
                for (int i : array)
                    map.put(i, new AtomicInteger());
                // now count all occurrences
                for (int i : array)
                    map.get(i).addAndGet(1);
                // now get rid of those where no duplicate exists
                HashSet<Integer> discards = new HashSet<Integer>();
                for (Integer i : map.keySet())
                    if (map.get(i).get() == 1)
                        discards.add(i);
                for (Integer i : discards) 
                    map.remove(i);
                return map;
            }
        
        }
        

        【讨论】:

        • 太棒了! :-) 稍作调整会有很大帮助!
        【解决方案6】:

        对我来说,最直接的答案是使用Collections.frequency 方法。类似这样的东西:

        // Example ArrayList with Integer values
        ArrayList<Integer> intList = new ArrayList<Integer>();
        intList.add(2);
        intList.add(2);
        intList.add(2);
        intList.add(2);
        intList.add(7);
        
        Set<Integer> noDupes = new HashSet<Integer>();
        noDupes.addAll(intList); // Remove duplicates
        
        for (Integer i : noDupes) {
            int occurrences = Collections.frequency(intList, i);
            System.out.println(i + " occurs " + occurrences + " times.");
        }
        

        如果您愿意,您可以将每个 Integer 与其出现次数进行映射:

        Map<Integer, Integer> map = new HashMap<Integer, Integer>();
        for (Integer i : noDupes) {
            map.put(i, Collections.frequency(intList, i));
        }
        

        【讨论】:

        • 你的第一个答案也很理想,刚刚试了一下,效果很好!谢谢!
        • 这看起来是O(N^2),而O(N log N) 是基于比较的排序的上限。 O(N) 如果适用非基于比较的排序,则可能。
        猜你喜欢
        • 2011-01-25
        • 2023-03-22
        • 1970-01-01
        • 2020-02-26
        • 2013-11-03
        • 1970-01-01
        • 1970-01-01
        • 2023-02-09
        • 1970-01-01
        相关资源
        最近更新 更多