poj 1229 字符串模糊匹配dp

之前虽然两过一段时间的dp,但是还是没有接触过这样的模糊匹配的状态转移,所以说状态转移是永远都学不完的东西啊。。。

其实之所以能够写出这样一道题,还是看了这位大哥的博客http://www.cnblogs.com/staginner/archive/2012/01/25/2329379.html

里面讲得比较全面吧,。。。

把通配符的意义改变一下,那么这样状态就能得到很好的记录。

引用那位大哥里面的话,那就是重新定义一下通配符的意义

   *:含义不变,至少配一个,多则不限。

    ?:只能配一个。

    !:可以配一个,也可以什么都不配。

    这样我们就得到了一个新旧通配符的转换公式:*->*, ?-> ?!!,!-> ??*。

 

View Code
  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<stdlib.h>
  5 #define N 600
  6 char str[N],A[N][N],B[N][N];
  7 int headA,headB,dp[N][N];
  8 void init()
  9 {
 10      scanf("%s",str);
 11      int i=0,j;
 12      headA=headB=1;
 13      while(str[i])
 14      {
 15            for(j=0;str[i]&&str[i]!='.';j++,i++)
 16                A[headA][j]=str[i];
 17            A[headA][j]='\0';
 18            headA++;
 19            if(A[headA-1][0]=='?')
 20            {
 21               A[headA++][0]='!';
 22               A[headA++][0]='!';
 23            }
 24            else
 25              if(A[headA-1][0]=='!')
 26              {
 27                 A[headA-1][0]='?';
 28                 A[headA++][0]='?';
 29                 A[headA++][0]='*';
 30              }
 31            if(!str[i])break;
 32            i++;
 33      }
 34      scanf("%s",str);
 35      i=0;
 36      while(str[i])
 37      {
 38            for(j=0;str[i]&&str[i]!='.';j++,i++)
 39                B[headB][j]=str[i];
 40            B[headB][j]='\0';
 41            headB++;
 42            if(B[headB-1][0]=='?')
 43            {
 44               B[headB++][0]='!';
 45               B[headB++][0]='!';
 46            }
 47            else
 48              if(B[headB-1][0]=='!')
 49              {
 50                 B[headB-1][0]='?';
 51                 B[headB++][0]='?';
 52                 B[headB++][0]='*';
 53              }
 54            if(!str[i])break;
 55            i++;
 56      }
 57 }
 58 void solution()
 59 {
 60      memset(dp,0,sizeof(dp));
 61      dp[0][0]=1;
 62      for(int i=1;i<headA;i++)
 63      {
 64         for(int j=1;j<headB;j++)
 65         {
 66             if(A[i][0]=='*'||A[i][0]=='?'||A[i][0]=='!'||B[j][0]=='*'||B[j][0]=='?'||B[j][0]=='!')
 67             {
 68                if(A[i][0]=='*')
 69                dp[i][j]=(dp[i][j]||dp[i][j-1]||dp[i-1][j-1]);
 70                if(A[i][0]=='?')
 71                dp[i][j]=(dp[i][j]||dp[i-1][j-1]);
 72                if(A[i][0]=='!')
 73                dp[i][j]=(dp[i][j]||dp[i-1][j]||dp[i-1][j-1]);
 74                if(B[j][0]=='*')
 75                dp[i][j]=(dp[i][j]||dp[i-1][j-1]||dp[i-1][j]);
 76                if(B[j][0]=='?')
 77                dp[i][j]=(dp[i][j]||dp[i-1][j-1]);
 78                if(B[j][0]=='!')
 79                dp[i][j]=(dp[i][j]||dp[i][j-1]||dp[i-1][j-1]);
 80             }
 81             else
 82             {
 83                if(strcmp(A[i],B[j])==0)
 84                dp[i][j]=dp[i-1][j-1];
 85                else
 86                dp[i][j]=0;
 87             }
 88         }
 89      }
 90      if(dp[headA-1][headB-1])
 91      printf("YES\n");
 92      else
 93      printf("NO\n");
 94 }
 95 int main()
 96 {
 97     int t;
 98     scanf("%d",&t);
 99     while(t--)
100     {
101        init();
102        solution();
103     }
104     return 0;
105 }

 

 

 

posted @ 2013-03-02 20:20  诺小J  阅读(450)  评论(0编辑  收藏  举报