计算列表中名称的出现次数并打印出最常用的名称

时间:2016-05-05 21:41:31

标签: java algorithm dictionary

所以我有一个清单

        List<String> names = new ArrayList<String>();
        names.add("Mike");
        names.add("Matthew");
        names.add("Kelly");
        names.add("Elon");
        names.add("Paul");
        names.add("Paul");
        names.add("Paul");
        names.add("Paul");
        names.add("Kelly");

我需要计算所有名称,然后按降序打印出3个最受欢迎的名称

Output:
Paul : 4
Kelly : 2
Mike : 1

我尝试了什么? 我尝试了从学到的最基本的东西到地图,树图和散列图。在过去的3场比赛中,我取得了一些成功,但我无法将它们降序排列。我从谷歌找到了一些教程,但它们都非常复杂,是的,我可以复制它们并让我的代码工作,但我更喜欢从中学习。

有什么建议是最明确的方法。因为我之前从未使用地图,所以在我写这篇文章的时候我对它们知之甚少。 最后,输出应如下所示:

Output:
Paul : 44,44%
Kelly : 22,22%
Mike : 11,11%

3 个答案:

答案 0 :(得分:0)

您可以使用Java 8:

来完成
    // creating a map with name as key and as value the number of time that name it repeat
    Map<String, Long> nameWithVlaues = names.stream()
                                            .collect(Collectors.groupingBy(s -> s, 
                                                 Collectors.counting()));

    // using a stream of de keyset of the precedent map
    nameWithVlaues.keySet()
                  .stream()
                  // sort the content of this stream using the value contained in the Map
                  .sorted((val1, val2) -> nameWithVlaues.get(val2).compareTo(nameWithVlaues.get(val1)))
                  // internal iterator over this stream
                  .forEachOrdered(name -> {
                  // getting the percent of ppl with this name
                  Long percent = (nameWithVlaues.get(name) * 100 / names.size());
                  // printing it
                  System.out.println(name + " : " + percent + "%");
                });

没有评论它似乎更清楚:D

    Map<String, Long> nameWithVlaues = names.stream()
                                        .collect(Collectors.groupingBy(s -> s, 
                                                 Collectors.counting()));

nameWithVlaues.keySet()
              .stream()
              .sorted((val1, val2) -> nameWithVlaues.get(val2).compareTo(nameWithVlaues.get(val1)))
              .forEachOrdered(name -> {
                Long percent = (nameWithVlaues.get(name) * 100 / names.size());
                System.out.println(name + " : " + percent + "%");
              });

答案 1 :(得分:0)

使用java 8的另一种解决方案可能是这样的:

    // creating a new comparator that compare two values by the number of their occurences in the list 
Comparator<String> comparatorOfValues = (val1, val2) -> {
  Long countVal1 = countIteration(val1, names);
  Long countVal2 = countIteration(val2, names);
  return - countVal1.compareTo(countVal2);
};

// maping function to write the result like this : NAME : 50%
Function<String, String> mapingFunction = name -> {
  return name + " : " + countIteration(name, names) * 100 / names.size() + "%";
};

// applying to names stream the comparator and the maping function and collect result as list
List<String> result2 = names.stream()
                            .distinct()
                            .sorted(comparatorOfValues)
                            .map(mapingFunction)
                            .collect(Collectors.toList());

result2.forEach(System.out::println);

计算列表中迭代次数的函数:

  // function that count how many values in that collection matching the name 
  public static Long countIteration(String name, Collection<String> collection) {
    return collection.stream()
                     .filter(val -> name.equals(val))
                     .count();
  }

答案 2 :(得分:0)

有几种方法可以做到这一点。对于初学者,您可以编写以下代码:

  1. 使用类似结构(HashMap)的哈希表,计算列表中每个名称的出现次数(每个名称的频率)。
  2. 现在您已拥有地图,您可以迭代其所有条目(即键值或名称频率)对,并选择频率最高的键(或名称)。还记得简单的线性搜索算法,同时保持目前为止所见的最大值吗?您可以在下一个练习中找到该百分比(暂时保留)。这将打印,例如{Paul: 4}。完成迭代后,您不应忘记从Map中删除此条目。
  3. 现在你知道如何进入下一个最频繁的进入,对吧?