如何找到包含所有给定字符的任何单词至少一次

时间:2012-05-12 22:00:08

标签: java

我使用此代码

                   while((dictionaryWord = br_.readLine()) != null) 
            {
                if(dictionaryWord.matches("^"+word.replace("*" , "." )+"$"))
                {   
                    incrementCounter();
                    System.out.println(dictionaryWord);
                }
            }

所需目标:word = dgo

输出:dog,god,dogma megalogdon等......

4 个答案:

答案 0 :(得分:1)

您可以在word中构建所有字符的Set<Character>,并对其进行迭代。如果一个字符不在dictionaryWord中,则dictionaryWord不适合。仅在全部显示时 - 打印dictionaryWord

    String word = "dog";
    String  dictionaryWord;
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    while((dictionaryWord = br.readLine()) != null)  {
        Set<Character> chars = new HashSet<Character>();
        for (char c : word.toCharArray()) {
            chars.add(c);
        }
        boolean match = true;
        for (Character c : chars) {
            String s = "" + c;
            if (!dictionaryWord.contains(s)) {
                match = false;
                break;
            }
        }
        if (match == true) 
            System.out.println(dictionaryWord);
    }

在上面的代码中,当然可以将集合创建移出while循环。

更有效的解决方案可能是从Set创建dictionaryWord,然后检查两个集合的交集是否与表示word的集合相同。
这将是:

    String word = "dog";
    Set<Character> set1 = new HashSet();
    for (char c : word.toCharArray()) {
        set1.add(c);
    }
    String  dictionaryWord;
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    while((dictionaryWord = br.readLine()) != null)  {
        Set<Character> set2 = new HashSet();
        for (char c : dictionaryWord.toCharArray()) {
            set2.add(c);
        }           Set<String> intersection = new HashSet(CollectionUtils.intersection(set1, set2));
        if (set1.equals(intersection)) {
            System.out.println(dictionaryWord);
        } else System.out.println("bad");
    }

使用apache commons中的CollectionUtils.intersection()

答案 1 :(得分:1)

public static void main(String[] args) {
  final BitSet reqChars = new BitSet(26);
  for (char c : "dog".toCharArray()) reqChars.set(Character.toLowerCase(c) - 'a');
  for (String w : new String[] {"god", "dogma", "megalogdon", "dorm"})
    if (hasAllChars(w, reqChars)) System.out.println(w);
}

public static boolean hasAllChars(String in, BitSet req) {
  req = (BitSet)req.clone();
  for (char c : in.toCharArray()) {
    req.set(Character.toLowerCase(c) - 'a', false);
    if (req.isEmpty()) return true;
  }
  return false;
}

答案 2 :(得分:1)

public static boolean containsAllCharacters(String word, Set<String> characters){
    int i = 0;
    int wordLength = word.getLength();
    while (i <= wordLength && characters.contains(word.get(i++)){}
    return i==wordLength;
}

答案 3 :(得分:0)

实际上,这个问题最有趣的部分是如何避免查看字典中的每个单词(尽管原始代码对此有所掩盖)。一个可能有趣的答案就是:

  1. 按发生频率制作一个包含26个字符的表格。
  2. 查找每个角色,获得最不频繁的角色。
  3. 然后执行包含该字符的单词匹配。
  4. 当然,这是假设单一匹配比正则表达式便宜。

    关于here主题的令人敬畏的维基百科页面。在这种情况下,差异可能不是很大,但例如在e和x的情况下,它会是。