Java中的快速有序列表匹配算法

时间:2014-01-16 16:52:01

标签: java algorithm list parsing matching

我有

形式的规则列表

L1 - > (A,B,C)

L2 - > (D,E),

L3 - > (F,G,A),

L4 - > (C,A)

.....

此列表包含约30,000条此类规则。

我有一个表格(X,Y,Z)的输入

这会创建一个方法

List <Rule> matchRules(input)

属于类RuleMatcher

我从一个非常简单明了的天真解决方案开始,为了让框架失效,让事情变得有效。

public RuleMatcher(Collection<Rule> rules) {
   this.rules = rules;
}

public Collection<Rule> matchRules(List<Token> input) {
   List<Rule> matchingRules = new ArrayList<>();
   for(Rule r: this.rules) {
        if(r.matches(input)) {
            matchingRules.add(r);
        }
   }
   return matchingRules; 
}

其中matches是一个非常简单的函数,用于检查长度是否相同,然后将每个标记检查为for循环。

这个matchRules函数被调用了数十亿次。


显然这是一个非常差的实现。根据我的分析器,至少有一半的执行时间花在了这个匹配函数上。

我在考虑两种可能的解决方案:

一个。某种Trie数据结构包含可以匹配的规则链。

B中。某种哈希函数。每个符号都有一个唯一的标识符。不幸的是,大约有8千个独特的符号,所以这可能很难。

℃。根据右侧的大小,规则中的令牌数量来调整hashmap。不幸的是,大多数规则大小相同,所以这甚至不值得。

d。一个很棒的解决方案,你们中的一个想出来。

我希望有人可以解决这个问题。


编辑:令牌只是一个具有唯一编号的对象。例如,“NN”是一个令牌。 “NN”的每个实例都完全相同。

匹配代码:

public boolean rhsMatches(List<Token> tokens) {
   if(tokens.size()!=rhsSize()) return false;
   for(int i = 0;i<rhsSize();i++) {
      if(!rightSide.get(i).equals(tokens.get(i)) {
        return false;
      }
   }
   return true;
}

它不是很漂亮,但很简单。

2 个答案:

答案 0 :(得分:1)

为什么不先对规则列表进行排序。然后,您可以二进制搜索匹配规则。

答案 1 :(得分:0)

对我而言,它看起来像是吸引一些工作者线程的完美场景。 匹配任务看起来彼此独立,划分规则列表并将匹配委托给工人(如果可能的话)。