首页 > 代码库 > XTU OJ 1163 查询成绩 (字符串+递归)

XTU OJ 1163 查询成绩 (字符串+递归)



查询成绩

Accepted : 52 Submit : 275
Time Limit : 3000 MS Memory Limit : 65536 KB

题目描述

波波同学是位大四的学生,同时也是一位考研er。为了考上北京邮电大学,他准备了很长时间。不久前,考研成绩终于公布了。波波登陆了成绩查询网站,发现自己密码竟然忘记了!但是幸好,他还记得其中的某些字母。请你判断,他记忆中的字母是否是正确密码的片段。

输入

多组样例,每组样例有两行。第一行为正确密码,第二行为波波记得的密码片段,‘*‘号表示波波不知道的密码片段,可能任意长,也可能为零。每行不超过110字符,首尾不会出现‘*‘。

输出

对于每组样例,能得到正确密码的输出yes,不能的输出no。

样例输入

abcdefg
ab*f
fnoeend
f*ed
ajfneogbb
aj*n*b

样例输出

yes
no
yes


Source

loying


昨天刚开始看到这道题的时候,觉得可以做,开始是想以 * 为分割符,把给的正确密码分成两个字符串,然后再用两个字符串和正确的密码相匹配。后来,队友给了我们一个特殊样例,比如像abcfabfe ab*fe我们按我们的思路就行不通,就换了种思路,队友说可以用最长公共子序列做,然后我们就做后面的题去了,把这道题交给他了,后来他说他的思路也错了,我们做另外一道题也没做出来。。今天看了别人的思路,其实我们按我们那种思路在想一下应该也能够想出来。


思路是这样的,进行递归匹配,分成两种情况,如果当前判断的不是 *,看两个字符串中的字符是不是相等,如果相等就递归查找 x+1,y+1; 如果是 *,这里多个*也当成一个 *处理,然后就看 x位置的字符和y+1位置的字符是否相等,如果想等就递归匹配 x+1,y+2;剩下的就是一些细节的处理了。

下面是ac的代码,参考了别人的,把第一个字符设为*;

#include <cstdio>
#include <cstring>
using namespace std;
char s[120],c[120];
int cmp(int x,int y)
{
    int len1,len2;
    len1=strlen(s);
    len2=strlen(c);
    if((y<len2)&&(x>=len1))  return 0;  //第一个字符串遍历完了,第二个还没完,说明就不匹配
    if(y==len2) return 1;  //第二个遍历完了 说明以及匹配到了
    if(c[y]=='*') 
    {
        while(c[y+1]=='*') y++; //多个* 的情况 
        int temp;
        for(int i=x;i<len1;i++)
        {
            if(s[i]==c[y+1]) 
            {
                temp=cmp(i+1,y+2); //这里y是*的那个位置,所以下一个位置应该是y+2;
                if(temp) return 1;
            }
        }
       return 0;
    }
    else
    {
        if(s[x]!=c[y]) return 0;
        else
            return cmp(x+1,y+1);
    }
}
int main()
{
    while(scanf("%s\n%s",s,c+1)!=EOF)
    {
        c[0]='*';
        puts(cmp(0,0)?"yes":"no");
    }
}

这里的c[0]=‘*‘感觉是个技巧,我把这里改了,感觉思路还是对的,样例也都通过了,但是还是wa;

#include <cstdio>
#include <cstring>
using namespace std;
char s[120],c[120];
int cmp(int x,int y)
{
    int len1,len2;
    len1=strlen(s);
    len2=strlen(c);
    if((y<len2)&&(x>=len1))  return 0;
    if(y==len2) return 1;
    if(c[y]=='*')
    {
        while(c[y+1]=='*') y++;
        int temp;
        for(int i=x;i<len1;i++)
        {
            if(s[i]==c[y+1])
            {
                temp=cmp(i+1,y+2);
                if(temp) return 1;
            }
        }
       return 0;
    }
    else
    {
        if(s[x]!=c[y]) return 0;
        else
            return cmp(x+1,y+1);
    }
}
int main()
{
    while(scanf("%s\n%s",s,c)!=EOF) //这里变成c
    {
        //c[0]='*';就这里改了一下
        puts(cmp(0,0)?"yes":"no");
    }
}
感觉思路也还是那样,就是wa大哭