【问题标题】:Find most appearing string in ArrayList在 ArrayList 中查找出现次数最多的字符串
【发布时间】:2015-01-10 01:15:26
【问题描述】:

如果我有这些字符串的 ArrayList...

“字符串1,字符串1,字符串1,字符串2,字符串2,字符串2,字符串3,字符串3”

如何找到此列表中出现次数最多的字符串?如果有任何重复,我想把它们放在同一个列表中并相应地处理。假设字符串列表可以是任意大小,我该怎么做。

据我所知:

public String getVotedMap() {
        int[] votedMaps = new int[getAvailibleMaps().size()];


        ArrayList<String> mostVoted = new ArrayList<String>();

        int best = 0;

        for(int i = 0; i < votedMaps.length; i++) {
            if(best > i) {
                best = i;
            } else if(best == i) {

            } else {

            }
        }

    }

getAvailibleMaps() 是我可以从中选择的地图列表(同样,可以获取任何大小) 谢谢!

【问题讨论】:

  • 这是您需要自己完成的学校作业还是您可以使用图书馆的实际代码?
  • @chrylis 好问题,因为如果你使用 Guava,你可以使用 Multiset 来完成这个壮举
  • @chrylis 我这样做是为了自娱自乐:D
  • @Loafayyy 那么尝试自己做而不是粘贴最小的尝试并要求其他人为您做不是更有趣吗?
  • @JasonC 我现在只是被卡住了,并且一直在尝试解决这个问题:/

标签: java arraylist


【解决方案1】:

如果您可以使用 java 8,这将为您提供最常用字符串的列表,如果列表为空,则抛出异常。

List<String> winners = strings.stream()
        .collect(groupingBy(x->x, counting()))  // make a map of string to count
        .entrySet().stream()
        .collect(groupingBy(                    // make it into a sorted map
                Map.Entry::getValue,            // of count to list of strings
                TreeMap::new, 
                mapping(Map.Entry::getKey, toList()))
        ).lastEntry().getValue();

【讨论】:

    【解决方案2】:

    使用HashMap

    基本思想是将所有值加载到哈希表中。哈希表很好,因为您可以为唯一键分配值。当我们将所有键添加到哈希表时,我们正在检查它是否已经存在。如果是,那么我们增加里面的值。

    在我们将所有元素插入哈希表之后,我们将一个一个地遍历哈希表并找到具有最大值的字符串。这整个过程是O(n)

    Map<String, Integer> map = new HashMap<String, Integer>();
    
    for(int i = 0; i < array.length(); i++){
       if(map.get(array[i]) == null){
          map.put(array[i],1);
       }else{
          map.put(array[i], map.get(array[i]) + 1);
       }
    }
    int largest = 0;
    String stringOfLargest;
    for (Map.Entry<String, Object> entry : map.entrySet()) {
       String key = entry.getKey();
       int value = entry.getValue();
       if( value > largest){
          largest = value;
          stringOfLargest = key;
       }
    }
    

    如果您想要多个 largest 字符串,那么不要只找到最大的并完成。您可以将所有最大的列表添加到可变列表中。

    例如:

    int largest = 0;
    for (Map.Entry<String, Object> entry : map.entrySet()) {
       String key = entry.getKey();
       int value = entry.getValue();
       if( value > largest){
          largest = value;
       }
    }
    ArrayList<Object> arr = new ArrayList<Object>();
    for (Map.Entry<String, Object> entry : map.entrySet()) {
       String key = entry.getKey();
       int value = entry.getValue();
       if( value == largest){
           arr.add(key);
       }
    }
    

    arr 现在存储所有最常出现的字符串。

    这个过程还是O(n)

    【讨论】:

    • 当有多个字符串出现相同的时间时,当它将两者都添加到列表中以进行进一步处理时,这是否有效?
    • 如果你能解释解决这类问题的好策略,以及解释你为什么选择以你的方式做这件事,这个答案会更有用。
    • @Loafayyy 当你在那个案例上测试它时,它有效吗?
    • @JasonC 是的,sortof... 它只选择最高的字符串之一,而如果有两个字符串出现相同的次数,它只选择一个。
    • 我添加的最后一部分应该得到所有最大的字符串
    【解决方案3】:

    只需遍历列表并保留一个 HashMap&lt;String,Integer&gt; 来计算字符串出现的次数,例如。

    Map<String,Integer> counts = new HashMap<String,Integer>();
    for(String s : mostVoted) {
        if(counts.containsKey(s)) {
            counts.put(s,counts.get(s)+1);
        } else {
            counts.put(s,1);
        }
    }
    // get the biggest element from the list
    Map.Entry<String,Integer> e = Collections.max(counts.entrySet(),new Comparator<Map.Entry<String,Integer>>() {
    
            @Override
            public int compare(Map.Entry<String,Integer> o1, Map.Entry<String,Integer> o2) {
                return o1.getValue().compareTo(o2.getValue());
            }
    
    });
    System.out.printf("%s appeared most frequently, %d times%n",e.getKey(),e.getValue());
    

    【讨论】:

    • 如果你能解释解决这类问题的好策略,以及解释你为什么选择以你的方式做这件事,这个答案会更有用。
    • 是的,我明白了。我试图找到出现最多的一个(或多个)字符串。这就是我遇到的麻烦。
    猜你喜欢
    • 2021-03-19
    • 1970-01-01
    • 2020-02-21
    • 2014-03-28
    • 2017-05-08
    • 2011-04-21
    • 1970-01-01
    相关资源
    最近更新 更多