[关闭]
@y20070316 2017-05-09T08:49:45.000000Z 字数 1328 阅读 1053

XSY 1004 - 通配符匹配

题目精选 字符串Hash dp


题意

  给定包含通配符 ?* 的字符串 ,将其与 进行匹配,问是否能完全匹配。(匹配的意思是一模一样)
   ? 可以恰好代替一个字符, * 可以代替 个以上任意多个的字符。

  
  

分析

  设 表示前 个通配符,匹配到 的第 位是否可行。

  边界:
  答案: 为通配符的个数

  转移:每次考虑使用上次的 * ,再将连续的一段进行匹配。于是我们在 的末尾补充 ? ,在 的末尾补充 #

实现

  1. #include <cstdio>
  2. #include <iostream>
  3. #include <cstring>
  4. #include <cctype>
  5. using namespace std;
  6. #define F(i,a,b) for (int i=(a);i<=(b);i++)
  7. #define LL unsigned long long
  8. const int N=100000;
  9. const int G=13131;
  10. const int M=15;
  11. LL pwr[N+5];
  12. char t[N+5]; int nt;
  13. LL h[N+5];
  14. int tot;
  15. int loc[M];
  16. int n;
  17. char s[N+5]; int ns;
  18. LL sh[N+5];
  19. int f[M][N+5];
  20. inline int eq(int x,int y,int l,int r) {
  21. LL hx=(x>y?0:h[y]-h[x-1]*pwr[y-x+1]);
  22. LL hy=(l>r?0:sh[r]-sh[l-1]*pwr[r-l+1]);
  23. return hx==hy;
  24. }
  25. int main(void) {
  26. #ifndef ONLINE_JUDGE
  27. freopen("sdchr.in","r",stdin);
  28. freopen("sdchr.out","w",stdout);
  29. #endif
  30. pwr[0]=1; F(i,1,N) pwr[i]=pwr[i-1]*G;
  31. scanf("%s",t+1); nt=strlen(t+1); t[++nt]='?';
  32. F(i,1,nt) h[i]=h[i-1]*G+t[i];
  33. F(i,1,nt) if (!isalpha(t[i]))
  34. loc[++tot]=i;
  35. cin>>n;
  36. F(c,1,n) {
  37. scanf("%s",s+1); ns=strlen(s+1); s[++ns]='#';
  38. F(i,1,ns) sh[i]=sh[i-1]*G+s[i];
  39. F(i,0,tot) F(j,0,ns) f[i][j]=0; f[0][0]=1;
  40. F(i,0,tot-1) {
  41. if (t[loc[i]]=='*')
  42. F(j,1,ns) f[i][j]|=f[i][j-1];
  43. F(j,0,ns)
  44. if (f[i][j]&&eq(loc[i]+1,loc[i+1]-1,j+1,j+loc[i+1]-loc[i]-1)) {
  45. if (t[loc[i+1]]=='?')
  46. f[i+1][j+loc[i+1]-loc[i]]=1;
  47. else f[i+1][j+loc[i+1]-loc[i]-1]=1;
  48. }
  49. }
  50. f[tot][ns]?printf("YES\n"):printf("NO\n");
  51. }
  52. return 0;
  53. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注