Wildcard Matching

来源:互联网 发布:淘宝大额优惠券在哪 编辑:程序博客网 时间:2024/06/10 04:41

参考http://blog.csdn.net/shiquxinkong/article/details/28104547

用贪心的思想。


分析:

  • * 可以匹配任意个字符,包括0个
  • 多个连续的*的作用相当于1个*。
  • * 后无其他字符,则直接匹配
  • 出现*p为 *,而*s为字符时,我们有两种选择,一种是跳过*p指示的*,也就是令*匹配0个字符,继续向后匹配。

  • 一种是我们需要用* 匹配多个字符,才能完成匹配。

  • * 后有其他字符,则在s串中向后找与该非*字符匹配的字符,若没找到,则不匹配,若找到了,则会有不同的情况。
  1. 用s中首次遇到的与p中*后的非*字符匹配 
                    
                    这当然是好的,再看另一种情况。
             2.不能用S 中首次遇到的与p中*后的非*字符与之匹配。
                   
                 如图所示,用s首次的e与p中的e匹配后,继续匹配的过程中发生了不匹配,但其实s串和p是匹配的,这就是说,要继续扩大 * 的作用域,将e也与* 进行匹配。
                                    
 但是通过前面的情况,我们发现p和s都跑了,p指向了g,s指向了第二个e。所以要记录下*后面的非*字符的位置,以便在后续发生不匹配时,重新进行匹配。 

实现:

[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1.  bool isMatch(const char *s, const char *p) {    
  2.     const char *backtrack_s = NULL;  
  3.     const char *backtrack_p = NULL;    
  4.   
  5.     while (*s) {    
  6.         //match   
  7.         if (*p == '?' || *s == *p) {    
  8.             ++s;    
  9.             ++p;    
  10.         }    
  11.         //don't match.  
  12.         else {    
  13.             //meet *  
  14.             if (*p == '*') {   
  15.                 //skip multiply  *.  
  16.                 while (*p == '*')    
  17.                     ++p;    
  18.                 if (*p == '\0')     
  19.                     return true;    
  20.                 //record the next position of *.  
  21.                 backtrack_s = s;    
  22.                 backtrack_p = p;    
  23.             }  
  24.             //   
  25.             else {//注意:判断前面是否出现了*    
  26.                 if (backtrack_p) {    
  27.                     //注意:在当前位置往后判断出现不相等的时候,再重新回到下一个位置重新往后比较    
  28.                     //其意义是继续扩大*的作用范围。  
  29.                     s = ++backtrack_s;    
  30.                       
  31.                     p = backtrack_p;//恢复p的位置    
  32.                 }    
  33.                 //既不匹配,前面又没有*,这就是真的不匹配了。    
  34.                 else return false;    
  35.             }    
  36.         }   
  37.     }  //end while  
  38.   
  39.     while (*p == '*')//处理p末端的*    
  40.         ++p;    
  41.     return (*s == '\0' && *p == '\0');    
  42. }    
=================================

如果用和regular expression matching一样的递归会超时:

bool isMatch(const char *s, const char *p){    if (s == NULL || p == NULL) return false;    if (*p == '\0') return *s == '\0';    if (*p == '*')    {        while (*p == '*') ++p;        while (*s != '\0')        {            if (isMatch(s, p)) return true;            ++s;        }        return isMatch(s, p);    }    else if ((*s != '\0' && *p == '?') || *p == *s)    {        return isMatch(s + 1, p + 1);    }    return false;}



0 0
原创粉丝点击