2 回答
TA贡献2011条经验 获得超2个赞
您的代码不适用于此输入:
HashMap<Integer, Integer> count = new HashMap<>();
count.put(1, 2);
count.put(2, 2);
count.put(4, 1);
因为您在mode = -1找到重复项后立即进行设置,而不是在最后进行设置。
您可以尝试以下代码,该代码在 EntrySet 上进行 2 次传递。一次找到最大值,然后检索具有该最大值的条目。
Integer max = count.values().stream()
.max(Integer::compareTo)
.orElse(-1);
List<Integer> maxEntries = count.entrySet().stream()
.filter(e -> e.getValue().equals(max))
.map(Map.Entry::getKey)
.collect(Collectors.toList());
Integer mode = maxEntries.size() == 1 ? maxEntries.get(0) : -1; //if there is a tie, mode is -1
System.out.println(mode);
为了能够存储大于 的值Integer,您可以使用Long和BigInteger。
TA贡献1797条经验 获得超4个赞
正如 Kartik 已经说过的,您是对的,您的代码中存在错误。最后还有一个循环:一旦找到与该值对应的键,您需要立即跳出它,或者mode可能在以后的迭代中再次更改导致不正确的结果。例如
new HashMap<>(Map.of(1, 3, 2, 1))
在这种情况下,您的代码将正确确定最高计数为 3。查找相应键的循环将首先将 3 更改为 1,然后将 1 更改为 2。因此结果为 2,这是不正确的。基本问题是您使用相同的变量 ,mode有两个目的,首先是模式的计数,其次是模式的 kay。不要那样做。混淆的风险太高了。
我想给出一个解决方案:
public static OptionalInt getModeIfUnique(Map<Integer, Integer> count) {
Optional<Integer> maxCount = count.values().stream().max(Comparator.naturalOrder());
OptionalInt modeKey = maxCount.flatMap(mc -> {
// Map containing only the entries having max count
Map<Integer, Integer> allModes = new HashMap<>(count);
allModes.values().removeIf(c -> c < mc);
if (allModes.size() == 1) {
return Optional.of(allModes.keySet().iterator().next());
} else {
return Optional.empty();
}
})
.map(OptionalInt::of)
.orElse(OptionalInt.empty());
return modeKey;
}
尝试一下:
// Kartik’s example - should give no mode
System.out.println(getModeIfUnique(Map.of(1, 2, 2, 2, 4, 1)));
// My example - should give 1
System.out.println(getModeIfUnique(Map.of(1, 3, 2, 1)));
// Empty map - should give no mode
System.out.println(getModeIfUnique(Map.of()));
输出:
OptionalInt.empty
OptionalInt[1]
OptionalInt.empty
添加回答
举报