为了账号安全,请及时绑定邮箱和手机立即绑定

从 HashMap 的一组值中查找模式,通过指示根本没有模式来打破关系

从 HashMap 的一组值中查找模式,通过指示根本没有模式来打破关系

墨色风雨 2022-07-06 18:35:45
HashMap 看起来像:Keys: 1, 2, 4Values: 1, 2, 1这里的模式是 2,因为它的值是一组值中最高的。然而,如果Keys: 1, 2, 4Values: 1, 2, 2然后就没有模式了。我得到了我拥有的较小测试用例的预期输出,但不确定这里是否存在不适用于较大输出的逻辑错误/如果值非常大并且不适合整数。“计数”是 HashMap。我的代码:            for (HashMap.Entry<Integer, Integer> entry : count.entrySet()) {                int curr = entry.getValue();                if (curr > mode) {                    mode = curr;                }                else if (curr == mode) {                    mode = -1;                }            }            if (mode != -1) {                for (HashMap.Entry<Integer, Integer> entry : count.entrySet()) {                    if (entry.getValue() == mode) {                        mode = entry.getKey();                    }                }            }
查看完整描述

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。


查看完整回答
反对 回复 2022-07-06
?
繁星coding

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


查看完整回答
反对 回复 2022-07-06
  • 2 回答
  • 0 关注
  • 89 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信