• regular expression matching DP


    这个题目,我从前天晚上(8月6号晚上)调试到现在(8月8号16:21),太心酸了,不好好总结一下,就太对不起自己了!
    这是题目:

    Implement regular expression matching with support for '.' and '*'.

    '.' Matches any single character.
    '*' Matches zero or more of the preceding element.
    
    The matching should cover the entire input 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", "a*") → true
    isMatch("aa", ".*") → true
    isMatch("ab", ".*") → true
    isMatch("aab", "c*a*b") → true
    
    动态规划,其实任何算法都是:核心思想+边界条件,其实不少的边界条件还是在调试过程中加上去的!!
    该题,我参考了网上的不少博客,自己总结如下:
         首先用一个二元数组来记录s和p的匹配情况(s代表源字符串,p代表目标字符串),比如res[i][j]为true表示 s[0... i-1]与p[0... j-1]已经匹配。
         假设当前需要判定s[0 ...i]与p[0... j]是否匹配,也就是res[i+1][j+1]是否为true:
    •      若p[j]=='*'
                   (1)若p[j-1]!='.'  则将res[i+1][j+1]置为true,只需满足以下3个条件当中的任意一个:
                             a. res[i+1][j]为true(此时*将其前面的那个字符只取1次)
    0 ..... i-1 i          
    0 ..... j-1 j       *    
                             b. res[i+1][j-1]为true(此时*将其前面的那个字符一次也不取,即二者为空了)
                             c. res[i][j+1]为true且s[i]==s[i-1]且s[i-1]==p[j-1]。(此时'*'将其前面的一个字符取了2次)。而且c选项还可以继续递归下去。
                       (2)若p[j-1]=='.'
                                  因为'.*'代表0个或多个'.',这可以匹配任何字符,所以只要res[i+1][j-1]或者res[i+1][j]中任意一个为true,剩下的res[i+1][j+1],res[i+2][j+1]......res[s.length()][j+1]就都可置为true。
    • 若p[j]!='*'
                        当(s[i]==p[j]或p[j]=='.')且res[i][j]为true时,res[i+1][j+1]置为true。
     
         最后return res[s.lenth()][p.length()]
     
     
    下面这些是我主要的参考资料,先附上自己的代码:
     1 class Solution {
     2 public:
     3      bool isMatch(string s, string p) {
     4           //constexpr int len1 = static_cast<const int>(s.length()), len2 = p.length();
     5           //bool  res[len1][len2] = { 0 };        这儿自己原本是想直接用数组,但是数组下标是要求常量表达式的,着急啊,现在也没解决
     6           int len1 = s.length() + 1, len2 = p.length() + 1;
     7           vector<vector<bool>> res(len1, vector<bool>(len2, false));
     8           res[0][0] = true;
     9           for (int i = 1; i < len2;i++)//没有这3句,  "aab", "c*a*b"  会不通过
    10           if (p[i - 1] == '*')
    11                res[0][i] = res[0][i - 2];
    12 
    13           for (int j = 0; j < len2-1; j++)
    14           {
    15 
    16                if (p[j] == '*')
    17                {
    18 
    19                     if (j>0&&p[j - 1] != '.')
    20                     {
    21                          for (int i = 0; i < len1-1; ++i)
    22                          if (res[i + 1][j - 1] || res[i + 1][j] ||i>0&& s[i - 1] == s[i] && s[i - 1] == p[j - 1]&& (res[i][j + 1]||res[i][j]))//这个地方一定要注意在具体的条件上加上限制就好了,千万别去将前面的for循环由i=0改为i=1
    23                               res[i + 1][j + 1] = true;
    24                     }
    25                     else
    26                     {
    27                          int i = 0;
    28                     //     for (; i < len1;)
    29                          //if (!res[i+1][j - 1] && !res[i][j])
    30                          //     ++i;     这个地方竟然写了个死循环
    31                          while (j>0&&i < len1-1&&!res[i + 1][j - 1] && !res[i+1][j])
    32                               ++i;
    33                          for (; i < len1-1; ++i)
    34                               res[i + 1][j + 1] = true;
    35 
    36                     }
    37                }
    38                else 
    39                {
    40                     
    41                     for (int i = 0; i < len1-1;++i)
    42                     if ((s[i] == p[j] || p[j] == '.') && res[i][j])
    43                          res[i + 1][j + 1] = true;
    44                }
    45           }
    46           return res[len1 - 1][len2 - 1];
    47      }
    48 };
     
    手里拿着一把锤子,看什么都像钉子,编程界的锤子应该就是算法了吧!
  • 相关阅读:
    消息(5)——WSE增强的web服务套件,MTOM附件
    消息(4)——WS附件传输,包体中的base64编码附件
    WCF消息之XmlDictionaryWriter
    Aptana使用技巧—Aptana2.0系列教程
    [f]获取URL中的参数[转]
    [f]获取元素在页面的位置getPos
    手机wap2.0网页缩放设置
    WPF SnapsToDevicePixels作用
    Silverlight获取控件绝对位置
    浏览器: F5 和 Ctrl+F5的区别
  • 原文地址:https://www.cnblogs.com/chess/p/4713506.html
Copyright © 2020-2023  润新知