zoukankan      html  css  js  c++  java
  • Wildcard Matching

    '?' Matches any single character.

    '*' Matches any sequence of characters(including the empty sequence).

     

    The matching should cover the entireinput string (not partial).

     

    The function prototype should be:

    bool isMatch(const char *s, const char*p)

     

    Some examples:

    isMatch("aa","a")→ false

    isMatch("aa","aa")→ true

    isMatch("aaa","aa")→ false

    isMatch("aa", "*")→ true

    isMatch("aa","a*") → true

    isMatch("ab","?*") → true

    isMatch("aab","c*a*b") → false

    Given [0,1,0,2,1,0,1,3,2,1,2,1],return 6.

     

           思路:本题与《Regular Expression Matching》类似,解题思路也可以照搬:在模式p中,一旦遇到字符’*’,就将从p+1开始于s+i(i=0,1,2,...)进行匹配,直到找到匹配的位置。但是需要注意一点,如果到了s的最后还是没能匹配的话,整个匹配过程就应该结束了,不应该在回退回去,去看s+i+1是否与p+1匹配,因为是没有意义的,代码如下:

    int isMatchcore(char*s, char* p, int *exitflag)
    {
        if(*s == '')
        {
            if(*p == '')  return 1;
            if(*p == '*' &&*(p+1) == '') return 1;
            *exitflag = 1;
            return 0;
        }
       
        if(*p != '*')
        {
            if(*p == *s ||*p == '?')   returnisMatchcore(s+1, p+1, exitflag);
            return 0;
        }
     
        if(*p == '*')
        {      
            if(*(p+1) =='')  return 1;
            int i = 0;
            int slen = strlen(s);
            while(i < slen &&(isMatchcore(s+i, p+1, exitflag)== 0))
            {
                if(*exitflag == 1) 
                {
                    return 0;
                }
                i++;
            }
            if(i < slen)    return 1;
            return 0;
        }
    }
     
    void predealpattern(char*p)
    {
        int i = 0;
        int plen = strlen(p);
     
        int j = 0;
        int lastchar = 0;
        for(i = 0; i <=plen; i++)
        {
            if(p[i] != '*'|| lastchar != '*')
            {
                p[j] = p[i];
                j++;
            }
            lastchar = p[i];
        }
    }
     
    int isMatch_recurse(char*s, char* p)
    {
        predealpattern(p);
        int exitflag = 0;
        return isMatchcore(s, p,&exitflag);
    }

    predealpattern函数用来对模式进行预处理,对于一连串的’*”,比如’****’,只保留一个’*’。这样做是为了减少递归的次数。exitflag的作用就是,一旦匹配到了s的最后还没有匹配成功,则整个匹配过程就应该结束了。开始没有注意到这一点,则在leetcode上测试直接超时。该递归程序最后的测试时间是16ms。下面是非递归版本,原理上是类似的,时间上更快一些,为8ms:

     

    int isMatch_loop(char*s, char* p)
    {
        char *lastp = NULL;
        char *lasts = NULL;
       
        while(*s != '')
        {
            if(*s == *p ||*p == '?')
            {
                s++;    p++;
            }
            else if(*p == '*')
            {
                p++;
                if(*p == '')  return 1;
                lastp = p;
                lasts = s;
            }
            else if(lastp != NULL)
            {
                p = lastp;
                s = ++lasts;
            }
            else
            {
                return 0;
            }
        }
     
        while(*p == '*')p++;
        return *p == '';
    }


    参考:

    https://github.com/haoel/leetcode/tree/master/algorithms/wildcardMatching

  • 相关阅读:
    hwclock设置时间的调用过程是怎样的?
    git如何获取获取子模块的代码?
    hwclock和date源码分析
    linux内核是如何支持深度睡眠(deep sleep)方式的?
    mac下如何安装python3?
    linux内核中的__cpu_suspend是在哪里实现的呀?
    linux下安装oracle需要的配置
    linux实操常用命令总结
    linux下vi命令大全
    PHP100精华:很靠谱linux常用命令
  • 原文地址:https://www.cnblogs.com/gqtcgq/p/7247136.html
Copyright © 2011-2022 走看看