【问题标题】:Hashmap with a boolean or hashset带有布尔值或哈希集的哈希图
【发布时间】:2013-11-29 00:49:06
【问题描述】:

如果hashmap 的值是Boolean,那么值得使用Hashset 吗?我的问题会令人困惑,但要提出正确的话也不容易。下面的代码解释了我的问题。该代码解决了以下问题Given some cubes, can cubes be arranged such that an input word can be formed from top view of cubes? 例如:假设一个假想的立方体只有三个表面,其中cube1: {a, b, c}cube2 {m, n, o},则可以形成单词an,但不能形成单词ap。对于这个问题,我有两种方法,使用HashMap<String, boolean> 或使用HashsetHashmap 的优点是它不会引起大量的重新散列。 hashset 的优点是代码看起来(至少对我来说)更小更干净。在这种情况下,正确的解决方案/行业范围内遵循的做法是什么?

选项 1:char[][] m 是立方体的集合,其中行是立方体,列是表面

public static boolean checkWord(char[][] m, String word) {
        final Map<Character, Boolean> charAvailable = new HashMap<Character, Boolean>();
        char[] chWords = word.toCharArray();

        for (char ch : chWords) {
            charAvailable.put(ch, true);
        }

        return findWordExists(m, charAvailable, 0);
    }

    private static boolean findWordExists (char[][] m, Map<Character, Boolean> charAvailable, int cubeNumber) {

        if (cubeNumber == m.length) {
            Collection<Boolean> booleanValues = charAvailable.values();
            for (boolean available : booleanValues) {
                if (available) return false;
            }
            return true;
        }

        for (int i = 0; i <  m[cubeNumber].length; i++) {
            if (charAvailable.get(m[cubeNumber][i]) == Boolean.TRUE) {
                charAvailable.put(m[cubeNumber][i], false);
                if (findWordExists(m, charAvailable, cubeNumber + 1)) {
                    return true;
                }
                charAvailable.put(m[cubeNumber][i], true);
            }

        }
        return false;
    }

选项 2:char[][] m 是立方体的集合,其中行是立方体,列是表面

public static boolean checkWord(char[][] m, String word) {
        final Set<Character> charAvailable = new HashSet<Character>();
        char[] chWords = word.toCharArray();

        for (char ch : chWords) {

            System.out.println(" adding: " + ch);
            charAvailable.add(ch);
        }
        return findWordExists(m, charAvailable, 0);
    }

    private static boolean findWordExists (char[][] m, Set<Character> charAvailable, int cubeNumber) {
        if (cubeNumber == m.length) {
            return charAvailable.isEmpty();
        }

        for (int i = 0; i <  m[cubeNumber].length; i++) {
            if (charAvailable.contains(m[cubeNumber][i])) {
                charAvailable.remove(m[cubeNumber][i]);
                if (findWordExists(m, charAvailable, cubeNumber + 1)) {
                    return true;
                }
                charAvailable.add(m[cubeNumber][i]);
            }
        }
        return false;
    }

【问题讨论】:

    标签: java hashmap hashset


    【解决方案1】:

    HashSet 将更加节省内存和时间,但会留下一些歧义取决于应用程序

    考虑这样一个场景,一个程序处理许多User 类型的自定义对象,并记录他们对“是或否”问题的回答。在此处理过程中,User 可能处于 3 种可能的状态:

    1. User 说“是”
    2. User 说“不”
    3. User 尚未处理

    单独使用HashSet(即没有额外的数据结构),根据具体情况,HashSet 中未找到的User 是否回答“否”或简单地回答“否”可能是不明确的尚未处理。 HashMap 虽然效率较低,因为它必须存储多个 Boolean 实例,但可以让您区分上面列出的 3 种情况。

    请注意,实际上,有很多情况可以消除第三种情况(例如,通过迭代每个 User 实例,因此您可以假设每个处理的 User 只遇到一次),而 HashSet 将是合适的选择。

    【讨论】:

    • HashSet 不会比 HashMap 更有效 - docs.oracle.com/javase/7/docs/api/java/util/HashSet.html "这个类实现了 Set 接口,由一个哈希表(实际上是一个 HashMap 实例)支持。"
    • @MichaelT:这很有趣,我不知道。你知道HashSet 对应的值是什么吗?我猜它映射到null 实例。
    • add method 存储了一个 Object,它是类的最终静态变量(名为 PRESENT)。
    【解决方案2】:

    使用Set 的解决方案可能更具可读性,并且更易于维护 - 例如,当您修改代码时,您可以避免一整类问题,例如“如果我在地图中放置 false 值会发生什么- 它会破坏我的代码吗?”。

    附带说明,Java 的HashSet 在内存方面效率很低,实际上在幕后使用了HashMap。尽管如此,在大多数情况下,最重要的是代码的可读性和可维护性,而不是像这样的实现细节。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-10-20
      • 2014-02-01
      • 2020-07-19
      • 1970-01-01
      • 1970-01-01
      • 2013-03-21
      • 2020-06-07
      • 2013-03-30
      相关资源
      最近更新 更多