java 输出最高分[重复]

voase2hg  于 2023-02-02  发布在  Java
关注(0)|答案(3)|浏览(127)
    • 此问题在此处已有答案**:

Convert List to Map<String, Integer>(4个答案)
1年前关闭。
我有以下球队名单和他们的得分:

List<String> teams = Arrays.asList("Dortmund 8", "Bayern 10", "Madrid 9", "Bayern 2", "Dortmund 4");

我需要输出得分最高的球队。如果得分相等,则输出得分最高的球队。在我的示例中,多特蒙德和拜仁得分相等,但拜仁得分最高。因此输出的是拜仁。下面是我现在的输出:

Map<String, Integer> map = new HashMap<>();
    for (String s : teams) {
        String[] rec = s.split(" ");
        int val = Integer.parseInt(rec[1]);
        map.put(rec[0], map.get(rec[0])==null ? val : map.get(rec[0]) + val);
    }
    System.out.println(map);

代码只是将每个团队的分数相加并保存在Map上。我不能改变我需要的方式。

zdwk9cvp

zdwk9cvp1#

int max = 0;
String bestTeam="";

Map<String, Integer> map = new HashMap<>();
for (String s : teams) 
{
    String[] rec = s.split(" ");
    int val = Integer.parseInt(rec[1]);
    int sum = map.get(rec[0])==null ? val : map.get(rec[0]) + val;
    map.put(rec[0], sum);
    if (sum>max) {
        max = sum;
        bestTeam = rec[0];
    }  
}

System.out.println("Max score winner team :" + bestTeam + "-["+max+"] goals");
  • 其他方法只是选择了最大条目。这里由**Alex Rudenko**和Nikolas Charalambidis编写的流方法是流应该如何处理这种情况的完美例子。与此相关的是使用Map,它只用于保存每个团队的总得分。排序是隐含在数组列表迭代中的。散列表从未涉及任何类型的排序。
  • 一月一日 *

这个名单的冠军不是多特蒙德,而是拜仁

  • 最好的队伍是在所有参赛队伍相加后得分最多的队伍。如果两支队伍的最高得分相同,那么最先达到最高得分的队伍将获胜。
  • 一米一分一秒 *

两队的最高分相同:22.拜仁获胜,因为它首先达到最高分。

  • 逻辑很简单,只要比较当前的最高分和当前的总和,条件是**sum>max而不是sum>=max**,就可以保证第一个达到最高分的队伍获胜。
    测试,工作:
    • 一米四分一秒**

8ehkhllq

8ehkhllq2#

使用Stream API、Regex(参见Regex101上的演示)以及PatternMatcher类有一种简单的方法。

([A-Za-z ]+) (\d+)

记住在Java中正则表达式必须进行双转义(\d-〉\\d):

Pattern pattern = Pattern.compile("([A-Za-z ]+)(\\d+)");

Optional<String> result = teams.stream()
    .map(pattern::matcher)
    .filter(Matcher::find)
    .collect(Collectors.collectingAndThen(
            Collectors.groupingBy(
                matcher -> matcher.group(1),
                LinkedHashMap::new,
                Collectors.summingInt(m -> Integer.parseInt(m.group(2)))),
            m -> m.entrySet().stream()
                    .max(Comparator.comparingInt(Entry::getValue))
                    .map(e -> e.getKey() + " " + e.getValue())));

Matcher的优点是它可以保存原始字符串(group())和捕获的组(group(int))。调用Matcher#find后,您可以使用捕获的组。获取编号所在的组,并将其用于groupingBy收集器下游的求和,以获得Map<String, Integer>,其中组名作为键,其总和为Map供应商LinkedHashMap::new确保有序Map。
随后的Collectors.collectingAndThen获取条目并找到具有最高得分的条目。只要处理准备好在输入列表为空的情况下返回空Optional,则整个流得到Optional<String>

**一个重要的注意事项:**考虑为这样的构造使用一个类(带有String nameint score)。进一步的操作会更容易。

dced5bon

dced5bon3#

基于流的解决方案应使用Collectors.groupingByCollectors.summingInt计算Map中的总目标/点,然后从其条目中获取最大值:

teams.stream()
     .map(s -> s.split(" ")) // Stream<String[]>
     .collect(Collectors.groupingBy(arr -> arr[0], 
              Collectors.summingInt(arr -> Integer.parseInt(arr[1])))) // Map<String, Integer>
     .entrySet().stream()
     .max(Map.Entry.comparingByValue())
     .ifPresentOrElse(e -> System.out.printf("Stream: %s - %d goals%n", e.getKey(), e.getValue()),
                      () -> System.out.println("No team found"));

输出:

Stream: Bayern - 12 goals
    • 更新**

然而,这种解决方案并不保证最早进球最多的球队将被选为获胜者。
对于List<String> teams = Arrays.asList("AEK 8", "Bayern 10", "Madrid 9", "Bayern 2", "AEK 4");,结果为AEK
类似的基于循环的版本可以使用Map::merge来计算目标/点的总值:

Map<String, Integer> totals = new HashMap<>();
String maxTeam = null;
int max = 0;
for (String record : teams) {
    String[] r = record.split(" ");
    if (max < totals.merge(r[0], Integer.parseInt(r[1]), Integer::sum)) {
        maxTeam = r[0];
        max = totals.get(maxTeam);
    }
}
System.out.printf("Loop: %s - %d goals%n", maxTeam, max);

输出:

Loop: Bayern - 12 goals

相关问题