题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6170
题意:给个只有[a-z]/*/.的正则式,拿去匹配一个字符串,问能不能匹配上。
f(i,j)代表正则式到i,匹配字符串到j时的匹配情况,a-z和.的匹配非常容易转移,难点在处理*上。
一开始想用树状数组维护i层与字符j相同的最左的下标的匹配情况,查询的时候从这个区间里任意一点转移过来,但是最后一组数据过不去。
自己造了一个数据,发现网上大部分的ac代码都过不了:
1
aaas
.as*.*
这应该输出no,大部分人输出的是yes。
重新看这道题,实际上直接暴力分类讨论*匹配可能遇到的所有情况了。
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 const int maxn = 2550; 5 char s[maxn], t[maxn]; 6 int ns, nt; 7 int f[maxn][maxn]; 8 9 signed main() { 10 // freopen("in", "r", stdin); 11 int T; 12 scanf("%d", &T); 13 while(T--) { 14 scanf("%s%s",t+1,s+1); 15 ns = strlen(s+1); nt = strlen(t+1); 16 memset(f, 0, sizeof(f)); 17 f[0][0] = 1; 18 if(s[2] == '*') f[2][0] = 1; 19 for(int i = 1; i <= ns; i++) { 20 for(int j = 1; j <= nt; j++) { 21 if(s[i] == '.') f[i][j] |= f[i-1][j-1]; 22 else if(s[i] == '*') { 23 f[i][j] = f[i-1][j] | f[i-2][j]; 24 if(t[j] == t[j-1] && (f[i-1][j-1] || f[i][j-1])) { 25 if(s[i-1] == t[j] && s[i-1] != '.') f[i][j] = 1; 26 else if(s[i-1] == '.') f[i][j] = 1; 27 } 28 } 29 else f[i][j] = f[i-1][j-1] & (s[i] == t[j]); 30 } 31 } 32 f[ns][nt] ? puts("yes") : puts("no"); 33 } 34 return 0; 35 }