zoukankan      html  css  js  c++  java
  • POJ1229 域名匹配

    给你两个域名,域名中包含一些通配符。

    * :匹配一个或任意多个部分

    ?:匹配一个或三个部分

    !:匹配三个以上部分。

    求这两个域名是否能够表示同一个域名?

    域名的长度不超过255.

    分析:设给出的域名为A,B,以f[i][j]表示域名A的前i个部分和域名B的前j个部分是否可能相同。类似于求最长公共子串的转移方式。

    f[i][j]=f[i-1][j-1]||f[i][j-1] 如果A[i]是*号。

    f[i][j]=f[i-1][j-1]||f[i-1][j-2]||f[i-1][j-3]  //如果A[i]是?号,但这么写是有问题的。如果B[j]也是通配符,就错了。

    于是我们势必将A[i]和B[j]一起考虑。这里就会有最多16种情况,当然其中有些情况可以合并。

    但是仍然有问题。比如A[i]是?号,B[j]是?号。

    如果方程这样写:f[i][j]=f[i-1][j-1]||f[i-1][j-2]||f[i-1][j-3]||f[i-2][j-1]||f[i-3][j-1] ,则如果B[j-1]是!号,则有问题。

    如果方程这样写:f[i][j]=f[i-1][j-1]||f[i][j-1]||f[i-1][j],则如果f[i][j-1]=1,但此时A[i]已经表示了三个部分了,没办法再表示B[j]了,又怎么办呢?

    所以这种转移是很不好办的。

    我们感觉到,如果通配符只能表示0个,1个或任意多个是比较好处理的。所以,我们将原有的通配符做一个转换。

    *意义不变

    ?变成只能匹配一个部分

    !变成只能匹配0个或1个部分。

    则原来的?=?!!(新符号)

    原来的!=??*

    这样的话,就好处理多了。

    先考虑*号,再考虑!号,再考虑?或非通配符。具体转移看代码。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<sstream>
     4 #include<cstring>
     5 #include<algorithm>
     6 using namespace std;
     7 int n,cas;
     8 #define MAXN 800
     9 char s[MAXN][MAXN],t[MAXN][MAXN];
    10 char ss[MAXN],tt[MAXN];
    11 bool  f[MAXN][MAXN];
    12 int cnt1=1,cnt2=1,pos=0;
    13 int convert(char *ss,char s[][MAXN])
    14 {
    15     int cnt=1,pos=0;
    16     int slen=strlen(ss);
    17      for(int i=0;i<slen;i++)
    18         {
    19             if(ss[i]!='.')
    20             {
    21             if(ss[i]=='!')
    22             {s[cnt++][0]='?';
    23                s[cnt++][0]='?';
    24                 s[cnt][0]='*';
    25             }
    26             else if(ss[i]=='?')
    27             {
    28                 s[cnt++][0]='?';
    29                 s[cnt++][0]='!';
    30                 s[cnt][0]='!';
    31             }
    32             else s[cnt][pos++]=ss[i];
    33             }
    34             else
    35             cnt++,pos=0;
    36         }
    37         return cnt;
    38     }
    39 int main()
    40 {
    41     scanf("%d
    ",&cas);
    42     while(cas--)
    43     {
    44         memset(f,0,sizeof f);
    45         memset(s,0,sizeof s);
    46         memset(t,0,sizeof t);
    47         gets(ss);
    48         //cerr<<ss<<endl;
    49         gets(tt);
    50         //cerr<<tt<<endl;
    51         cnt1=convert(ss,s);
    52         cnt2=convert(tt,t);
    53         f[0][0]=1;
    54         for(int i=1;i<=cnt1;i++)
    55             for(int j=1;j<=cnt2;j++)
    56             {
    57                 if(s[i][0]=='*')
    58                     f[i][j]=f[i][j]||f[i][j-1]||f[i-1][j-1];
    59                 if(t[j][0]=='*')
    60                     f[i][j]=f[i][j]||f[i-1][j]||f[i-1][j-1];
    61                 
    62                 else if(s[i][0]=='!')
    63                     f[i][j]=f[i][j]||f[i-1][j]||f[i-1][j-1];
    64                 else if(t[j][0]=='!')
    65                     f[i][j]=f[i][j]||f[i][j-1]||f[i-1][j-1];
    66                 else if(s[i][0]=='?'||t[j][0]=='?')
    67                 {
    68                     f[i][j]=f[i][j]||f[i-1][j-1];
    69                 }
    70                 else if(strcmp(s[i],t[j])==0)
    71                     f[i][j]=f[i-1][j-1];
    72             }
    73        if(f[cnt1][cnt2]==0)
    74        printf("NO
    ");
    75        else printf("YES
    ");
    76        }
    77     }
    View Code
  • 相关阅读:
    转 UICollectionView 详解
    springboot配置ssl证书
    服务器ganglia安装(带有登录验证)
    eureka配置说明
    Servlet中获取请求参数问题
    apidoc学习(接口文档定义取代word)
    markdown语法
    JVM分析
    ftp上传或下载文件工具类
    ubuntu命令安装
  • 原文地址:https://www.cnblogs.com/hefenghhhh/p/4650962.html
Copyright © 2011-2022 走看看