- 遇到特殊字符的时候,我们就有多种处理方式了,也就是所谓的岔路口:
- “*”有多种匹配方案,可以匹配任意个文本串中的字符,我们就先随意的选择一种匹配方案,然后继续考察剩下的字符。如果中途发现无法继续匹配下去了,我们就回到这个岔路口,重新选择一种匹配方案,然后再继续匹配剩下的字符。
- "?"有两种匹配方案,匹配0个或者1个:我们就先选择匹配0个的方案,然后继续考察剩下的字符。如果中途发现无法继续匹配下去了,我们就回到这个岔路口,重新选择匹配1个的方案,然后再继续匹配剩下的字符。
- 遇到非通配符时,我们就直接跟文本的字符进行匹配,如果相同,则继续往下处理;如果不同,则回溯(即当前一段程序结束,回到上一个调用的程序入口)。
C++版本代码如下
#include<iostream>
#include<string>
#include <limits>
using namespace std;
bool matched = false;
void match(int ti, int pj, char text[], int tlen, char patten[], int plen){
// 如果已经匹配了,就不要继续DFS了
if(matched)
return ;
// 正则表达式到结尾了
if(pj == plen){
// 如果文本串也到结尾了
if(ti == tlen)
matched = true;
return ;
}
// 下面是回溯法的“for循环”判断这一步有几种可能
// 1、正则表达式当前字符为" * "
if(patten[pj] == '*'){
// 可以匹配0个或者多个字符
for(int i = 0; i < tlen - ti; i++)
match(ti + i, pj + 1, text, tlen, patten, plen);
}
// 2、正则表达式当前字符为" ? "
else if(patten[pj] == '?'){
// 匹配0个任意字符
match(ti, pj + 1, text, tlen, patten, plen);
// 匹配1个任意字符
match(ti + 1, pj + 1, text, tlen, patten, plen);
}
// 3、正则表达式当前字符与文本串相等
else if(patten[pj] == text[ti]){
match(ti + 1, pj + 1, text, tlen, patten, plen);
}
// 否则就回溯
}
int main()
{
match(0, 0, "abcdef", 6, "a?c*f", 5);
cout<<matched<<endl;
return 0;
}