使用正则表达式进行搜索:C ++

时间:2014-02-23 01:56:54

标签: c++ search tree trie

好的我必须使用“* all”之类的输入搜索Trie树,其中*可以是任何字符。我知道使用regex_match匹配搜索字符串,就像其他树一样,在那里搜索整个单词。但由于Trie的搜索算法是按字符进行的,因此我无法将常规搜索算法转换为我的需求。

以下是没有*​​

的trie搜索的未触及的常规代码
 bool Trie::searchWord(string s){
Node* cur = root;

while(cur != NULL){
    for(int i = 0; i < s.length(); i++){
        Node* tmp = cur->findChild(s[i]);
        if(tmp == NULL){
            return false;
        }//end if
        cur = tmp;
    }//end for
    if(cur->wordMarker()){
        return true;
    }else{
        return false;
    }//end if-else
}//end while
return false;
}//end searchWord(s)

Node* Node::findChild(char c){
for(int i = 0; i<mChildren.size(); i++){
    Node* tmp = mChildren.at(i);
    if(tmp->content() == c){
        return tmp;
    }//end if
}//end for
return NULL;
}//end findChild(c)

这是我尝试修改它。它适用于常规单词,但不适用于*

bool Trie::searchWordRegex(string s){
Node* cur = root;

while(cur != NULL){
    regex reg ;
    for(int i = 0; i < s.length(); i++){
        if(s[i] == '*'){
            reg = regex("(\\w)");
        }//end if
        Node* tmp = cur->findChildRegex(s[i], reg);
        if(tmp == NULL){
            return false;
        }//end if
        cur = tmp;
    }//end for
    if(cur->wordMarker()){
        return true;
    }else{
        return false;
    }//end if-else
}//end while
return false;
}//end searchWord(s)

Node* Node::findChildRegex(char c, regex r){
for(int i = 0; i<mChildren.size(); i++){
    Node* tmp = mChildren.at(i);
    string s(1,tmp->content());
    if(tmp->content() == c || regex_match(s, r)){
        return tmp;
    }//end if
}//end for
return NULL;
}//end findChild(c)

有没有办法可以修复这些功能?或者像其他树的regex_match一样容易吗?

谢谢。

1 个答案:

答案 0 :(得分:0)

由于您将'*'称为字符通配符,因此意图有点令人困惑,但您引用的是正则表达式匹配(实际的正则表达式字符通配符为'。')。我将尝试回答这个问题,假设意图是支持对trie进行完整的正则表达式搜索,或者在trie中搜索通配符。

在Trie中正则表达式匹配

trie通常用于支持快速O(m)操作。它不是处理正则表达式的通常有效的结构。

regular expression matching(DFA / NFA和回溯)有几种算法,并且为了在trie搜索中支持它们,你实际上必须实现一个经过修改的算法来支持子搜索迭代和回溯在trie中用于收集状态/匹配的正则表达式可以匹配。这将具有最低的渐近复杂度,可能是最有效的。

...然而

t几乎具有相同的渐近复杂度来迭代特里结构中的所有字符串,并使用std::regexstd::regex_match对正则表达式匹配进行测试。此外,它还使您无需实现相对复杂的正则表达式引擎。

Trie中的通配符匹配

但是,修改代码以支持通配符搜索非常简单。不是使用显式字符搜索每个级别,而是针对通配符('*'或'。')检查搜索字符s[i],如果匹配,则可以进入任何子尝试,并且增量i。虽然,有一点需要注意,你需要能够转义你选择的任何字符作为通配符,因此它仍然是存储在trie中的字符串中的有效字符。