华为机试——含有通配符的字串匹配

    今天去华为参加暑期实习生机试,一共三个题目,前面两个较为简单(二选一)。1、给定一个日期(如2012年4月15日),判断是周几?2、把一个字符串中的非字母删掉,并且将大写字母小写。3、求一个字符串2在字符串1中的最先匹配,字符串2中可以使用通配符*,即*可以代替任意字符。例如,str1[]="abcdefgh";str2[]="a*f";则输出结果是“abcdef”.

    第三个题目是选作题目,监考的帅哥一再提醒我们,最好做一下第三个题目,感觉第三个题目,对我来说的确有点复杂。我在机试现场写的程序是错误的,到了快结束的时候,才把思路理清楚。晚上回到实验室之后,花了将近2个小时的时间,才把程序按照思路写出来,且没有考虑算法的时间复杂度。下面把我的思路以及代码放在下面,希望大家多多批评指教。

    思路:若str2是普通字符串,即不含有通配符*,则只要有两重循环就可以求得最先匹配。现在,str2中可以使用通配符“*”,也就是说,我们在使用普通的算法的时候,只要把*的作用给考虑进去,那么问题就引刃而解了。代码如下所示,代码中的测试用例都可以正确的求解。


/*查找字符串2在字符串1中的最先匹配,字符串2中可以使用通配符
    例如、str1="abcedfgh";str2="a*f";则结果为"abcdef"
*/
#include <stdio.h>
#include <string.h>

void FindMatch(char *pszIn,char *pszKey,char *pszOut){
    //*********************************************
    int i=0,j=0,start=0,end=0;
    int len1=strlen(pszIn),len2=strlen(pszKey);
    int find=0;

    for(start=0;start<len1;start++){
        i=start;
        for(j=0;j<len2 && i<len1;j++){
            if(pszIn[i]!=pszKey[j] && pszKey[j]!='*')//本次匹配失败,从pszIn的下一个字符重新开始比较
                break;
            else if(pszIn[i]==pszKey[j] && pszKey[j]!='*'){//当前位置的字符相等,比较下一个位置的
                i++;
                if(j==len2-1){
                    find=1;
                    end=i;
                }
            }else if(pszKey[j]=='*'){//查找pszIn中从i位开始,到结束是否存在pszKey[j+1]
                
                if(j+1>len2-1){//pszKey[j]是最后一个元素
                    end=i;
                    find=1;
                    break;
                }else if(pszKey[j+1]=='*')
                    continue;
                else{//pszKey[j+1]是正常字母,在pszIn中从i位开始查找,若找到则继续比较下一位;否则,一定不会匹配
                    for(;i<len1;i++)
                        if(pszIn[i]==pszKey[j+1]){
                            j++;
                            i++;
                            if(j==len2-1){
                                find=1;
                                end=i;
                            }
                            
                            break;
                        }

                        /*if(i==len1){
                            find=0;
                            break;
                        }*/

                }

            
            }//else if

        }//for(j=0;j<len2;j++)
        if(find==1){
            for(int t=start;t<end;t++)
                pszOut[t]=pszIn[t];
            break;//已经成功找最先匹配
        }
    }//for(start=0;start<len1;start++)

    if(find==0)
        printf("\n不存在匹配");

    //*********************************************

    return;
}
int main(){
    char *pszIn="abcdefgh";
    char *pszKey="a*f";
    char pszOut[100]={'\0'};
    FindMatch(pszIn,pszKey,pszOut);
    printf("\n1、The result is:%s\n",pszOut);
    
    memset(pszOut,0,100);
    pszKey="a***f";
    FindMatch(pszIn,pszKey,pszOut);
    printf("\n2、The result is:%s\n",pszOut);

    memset(pszOut,0,100);    
    pszKey="a**f*h";
    FindMatch(pszIn,pszKey,pszOut);
    printf("\n3、The result is:%s\n",pszOut);
    
    memset(pszOut,0,100);    
    pszKey="*h";
    FindMatch(pszIn,pszKey,pszOut);
    printf("\n4、The result is:%s\n",pszOut);
    
    memset(pszOut,0,100);    
    pszKey="a*";
    FindMatch(pszIn,pszKey,pszOut);
    printf("\n5、The result is:%s\n",pszOut);
    
    memset(pszOut,0,100);    
    pszKey="*f*";
    FindMatch(pszIn,pszKey,pszOut);
    printf("\n6、The result is:%s\n",pszOut);
    
    memset(pszOut,0,100);    
    pszKey="a**f*h";
    FindMatch(pszIn,pszKey,pszOut);
    printf("\n7、The result is:%s\n",pszOut);
    return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值