带有布尔或哈希集的Hashmap

时间:2013-11-29 00:49:06

标签: java hashmap hashset

如果hashmap的值是Boolean,那么值得使用Hashset吗?我的问题会让人感到困惑,但也不容易构建正确的词语。下面的代码解释了我的问题。该代码解决了以下问题Given some cubes, can cubes be arranged such that an input word can be formed from top view of cubes?,例如:假设一个只有3个表面的假想立方体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;
    }

2 个答案:

答案 0 :(得分:1)

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

作为旁注,Java的HashSet内存非常低效,实际上使用了HashMap。尽管如此,在大多数情况下,最重要的是代码可读性和可维护性,而不是像这样的实现细节。

答案 1 :(得分:1)

HashSet将提高内存效率并节省时间,但会根据应用程序留下一些歧义

考虑程序处理某些类型User的许多自定义对象的情况,并将其答案记录为“是或否”问题。在此处理期间,User可能存在3种可能的状态:

  1. User说“是”
  2. User说“不”
  3. User尚未处理
  4. 单独使用HashSet(即没有其他数据结构),根据情况,User中找不到的HashSet是否已回复可能不明确“没有”,或者根本没有被处理过。 HashMap虽然效率较低,因为它必须存储多个Boolean个实例,但您可以区分上面列出的3种情况。

    请注意,在实际应用中,很多情况下可以消除第三种情况(例如,通过迭代每个User实例,这样您就可以假设每个处理过的User只遇到一次),并且HashSet将是合适的选择。