• CDOJ1616 小小的寻宝大将


      题目地址http://acm.uestc.edu.cn/problem.php?pid=1616

      题目分析:两个字符串ab,其中b仅由大写英文字母构成,a除了有大写英文字母,还有‘*,?’;判断a能否是b的子串。其中:

    *’:表示此处有若干个待辨识的字符(可以是0个!);

    ‘?’:表示此处恰有一个待辨识的字符。

      解题思路:这个问题中包含着相同结构的子问题:

    a[i]及之前的子串已经和b[k]及之前的子串匹配上了,并且a[i+1]是‘*’,

    那么如果以a[i+1]b[k+1]开始的子串匹配上,整个串就匹配上了!详见代码注释。。。。。。

      源代码

    #include<cstdio>
    #include<cstring>

    bool check(char a[2000],char b[2000])
    {
    int lena,lenb,i,j,k,p,sign,num;
    lena=strlen(a);
    lenb=strlen(b);

    if(lena==0)//特判1:判断a是否为空?若为空,a就是b的子串!
    return true;
    for(i=0;i<lena;i++)
    if(a[i]!='*')
    break;
    if(i==lena) //特判2:判断a是否全是‘*’,若是,a就是b的子串!
    return true;
    if(lenb==0 && lena>0)//特判3:如果b串是空串,a一定不是b的子串!
    return false;

    for(i=0;i<lena;i++)
    if(a[i]!='*' && a[i]!='?')//找到a中第一个不是'*'和'?'的字符的位子p
    {
    p=i;
    break;
    }
    num=0;
    for(j=p-1;j>=0;j--)//统计p之前有多少个'?',存在num中
    {
    if(a[j]=='?')
    num++;
    }
    for(i=0;i<lenb;i++)//b串从前往后扫。。。
    {
    if(a[p]==b[i])//如果和a第一个字母匹配。。。
    {
    if(i>=num)//并且b串在字符i之前已包含足够多的字符来满足a串中的‘?’
    {
    sign=0;
    for(j=p+1,k=i+1; j<lena && k<lenb; j++,k++)//a和b字符开始逐一匹配。。。
    {
    if(a[j]==b[k])//又匹配上一个,继续!
    continue;
    else if(a[j]>='A' && a[j]<='Z')//一个字符没匹配上,那肯定匹配不上咯。。。
    {
    sign=1;//信号量:没匹配上!
    break;
    }
    else if(a[j]=='?')//a串在这里有一个带辨识的字符,随便b这里是什么吧,继续!
    continue;
    else if(check(a+j,b+k)==true)//这种情况就是a这里是'*'了,看后面的子串是否匹配上,相同结构的子问题!递归!
    {
    j=lena;//表示a串匹配完了,j到达lena是在递归调用中完成的,这里让它直接到头就是了!
    break;
    }
    }
    if(sign==0)//上面循环结束前没出现匹配错误。。。
    {
    if(j==lena)//并且a中全部字符都匹配完了!!!
    return true;
    }
    }
    }
    }
    return false;
    }

    int main()
    {
    int t;
    char a[2000],b[2000],ch;
    scanf("%d",&t);
    while(t--)
    {
    scanf("%c",&ch);
    while(ch!='\n')
    scanf("%c",&ch);
    scanf("%s%s",a,b);
    if(check(a,b)==true)
    printf("YES\n");
    else
    printf("NO\n");
    }
    return 0;
    }

     

  • 相关阅读:
    [Codevs 1230]元素查找(手写哈希表)
    bat+sqlcmd 批量执行脚本
    为Redmine的项目加上起止时间
    SDUT 1068-Number Steps(数学:直线)
    对象间的联动--观察者模式
    《千与千寻》给读者带来了什么?
    二叉树中和为某一值的路径
    关于Win8 用不了USB转串口驱动
    Android Socket编程学习笔记
    java中的正则操作总结
  • 原文地址:https://www.cnblogs.com/Lattexiaoyu/p/2296175.html
Copyright © 2020-2023  润新知