Regular Expression Matching

题目: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

思路:

牢记一点,题目中所讲preceding character 代表的是出现*字符的前面一个字符。

本题的一种思路是递归,容易理解,顺便讲下具体步骤:

对于s[0...i-1]  p[0...j-1]

首先判断当前位置下一个字符是否是*,

如果是*,直接排除当前两个字符,递归调用下面的,如果递归调用返回false,再进行下一步,就是考虑preceding character,它指的是*之前的一个字符,接下来就看s下面的字符与之前的这个字符是否一样或者它本身就是 “.” 。这是一种情况。

对于第二种,下一个字符不是*,这种情况较为简单,如果当前比较的两个字符相同或者p中的字符是".",返回true。


对于动态规划方法,其实思路一样,

首先考虑的是初始化问题,p中首字符一定不是*,暂且当成一个说明吧,不解释,我也解释不了。

对于字符不是*得,程序写的很清晰,不再赘述。

如果字符是*,就是判断之前两位,先考虑0个字符的

代码:

class Solution {
public:
//https://leetcode.com/problems/regular-expression-matching/
//记住 本题与wildcard matching不同的
    /*bool isMatch(string s, string p) {
        //if (s.empty()) return p.empty();  不需要判断s是否为空,因为后面万一出现A*之类的,反正A可以算0次
        //但是当p是空的时候,s一定要是空的
        if (p.empty()) return s.empty();
        if(p[1]!='*'){
            if(p[0]==s[0]||(p[0]=='.'&&s[0]!='')){
                //s不能结尾
                return isMatch(s.substr(1), p.substr(1));
            }else 
                return false;
        }else{
            if (isMatch(s, p.substr(2)))  return true;////代表前面的字符出现0次   而且还算是迭代,方便后面继续出现***
            int index=0;
            while(index<s.size()&&(s[index]==p[0]||p[0]=='.')){
                if(isMatch(s.substr(++index), p.substr(2)))   return true;
            }//这个时候先是让前面的一个字符出现一次,再是2次....
            return false;
        }
    }*/
    bool isMatch(string s, string p){
        /*
        f[i][j]==ifs[0...i-1] p[0...j-1]
        */
        int m=s.size(),n=p.size();
        
        vector<vector<bool> > f(m+1,vector<bool>(n+1,false));
        //初始化 initialize
        f[0][0]=true;
        for(int i=1;i<=m;i++){
            f[i][0]=false;
        }
        for(int i=1;i<=n;i++){
            f[0][i]=i>1&&p[i-1]=='*'&&f[0][i-2];//因为此时是空的
        }
  
        for(int i=1;i<=m;i++){
            for(int j=1;j<=n;j++){
                if(p[j-1]!='*'){
                    f[i][j]=f[i-1][j-1]&&(p[j-1]==s[i-1]||p[j-1]=='.');
                }else{
                    //p[0] 不能还*
                    f[i][j]=f[i][j-2]||(    f[i-1][j]&&(p[j-2]==s[i-1]||p[j-2]=='.' )  );
                    // f[i][j]=f[i][j-2]|| f[i-1][j-2]&&p[j-2]==s[i-1]  || f[i-2][j-2]&&p[j-2]==s[i-1]&&p[j-2]==s[i-2] ...
                    //           f[i-1][j]=f[i-1][j-2]|| f[i-2][j-2]&&p[j-2]==s[i-2] || ....
                    //f[i][j] = f[i][j - 2] || ((s[i - 1] == p[j - 2] || '.' == p[j - 2]) && f[i - 1][j]);
                }
            }
        } 
        return f[m][n];
    }
};

//http://blog.csdn.net/u010025211/article/details/46841037


原文地址:https://www.cnblogs.com/jsrgfjz/p/8519837.html