在Java的TreeSet或Collections.BinarySearch中使用正则表达式

时间:2013-12-08 02:11:51

标签: java regex search optimization tree

我正在尝试创建一个匹配的程序,当给出一个单词的正则表达式“C [A-Z] T”时,找到所有与单词列表中的正则表达式匹配的单词。我的例子的匹配将是CAT,CUT,COT。

我的目标是尽可能快地为非常大的单词列表。我尝试使用Java的TreeSet实现,但搜索需要很长时间,因为我必须迭代树中的每个单词。即使我在将列表放入树之前随机化列表,搜索速度也太慢了。

所以我的问题是,我可以使用内部Contains(),还是Java提供的其他数据结构,可以使用正则表达式?感谢..

我正在考虑使用AVL或Red-Black“hashmap”(但不是真的),长度为键,单词为值。这意味着我需要允许多个相同的键,但每个键映射到不同的值。所以我的get会返回一个值List,而不是一个值。有什么地方我可以找到这种数据结构的实现吗?或者至少是一个让我开始的基地..我真的不愿意自己动手​​。

到目前为止,这是我的代码:

public class WordSearch {
    SortedSet<String> tree = new TreeSet<String>();
    List<String> list = new ArrayList<String>();

    public WordSearch(List<String> allWords) {
        // long seed = System.nanoTime();
        // Collections.shuffle(allWords, new Random(seed)); // randomize
        tree.addAll(allWords);
    }

    public List<String> solutions(String pattern, int max) {
        pattern = pattern.toLowerCase().toUpperCase();
        pattern = pattern.replace("*", "[A-Z]");
        Pattern find = Pattern.compile(pattern);
        int count = 0;
        ArrayList<String> result = new ArrayList<String>();
        Iterator<String> it = tree.iterator();
        while (count < max) {
            while (it.hasNext()) {
                String word = it.next().toLowerCase().toUpperCase();
                Matcher match = find.matcher(word);
                if (match.matches()) {
                    result.add(word);
                    count++;
                }
            }
            break;
        }
        return result;
    }
}

1 个答案:

答案 0 :(得分:1)

如果你事先了解你的正则表达式/模式,你可以建立类似于布隆过滤器的东西,但这与构建Collections matchesPattern0matchesPattern1^C[A-Z]T$完全不同等等,这基本上是数据库索引的工作原理。您可能只需要一个前缀树。

在您的情况下,数据结构有用的唯一方法是锚定正则表达式,即指定第一个或最后一个字符或字符范围。否则,无论如何,您必须遍历整个数据结构。基本上,Pattern情况是所以特定的,没有人出去为此建立一个优化的数据结构。

如果你感觉聪明并且迫切需要这个,你最好的选择是将CAT转换为“min”和“max”的方法,以便D和{{1然后使用SortedSet.subSet,并对结果应用过滤器。但实际上,这种优化很少有效。