Regular Expression Matching

  解法一:递归spa

  刚开始简单地觉得扫描字符串,而后对比就好了。但因为有“*”,没法考虑全部状况。所以这题使用了递归的方法来解,即不断地缩短字符串长度,直到分解为最基础的几种状况。因为”*"表示重复任意次数,所以应该有一个回溯的过程。固然重复次数最大是带匹配的字符串的的长度。code

  难度在于基础状况的处理以及如何递归。基础状况须要仔细考虑才不会遗漏。好比s为空,p为空等。代码以下:blog

 

class Solution {
public:
    bool isMatch(const char *s, const char *p) {
        const char *s_pos=s;
        const char * p_pos=p;
        
        if(*s!='\0'&&*p=='\0')
        return false;

        if(*s=='\0'&&*p=='\0')
            return true;
        if(*s=='\0'&&*p!='\0')
        {
            if(*(p+1)=='*')
                return isMatch(s,p+2);
            return false;
        }
        
        if(*(p+1)!='*')
            return ((*s==*p)||(*p=='.'))&&isMatch(s+1,p+1);
        else
        {
            //caculate the max num of repeating a char
            int c=0;
            while(*(s+c)!='\0')
                c++;

            bool m=true;
            for(int i=0;i<=c;i++)
            {
                //cout<<"i: "<<i<<endl;
                m=true;
                for(int j=0;j<i;j++)
                {
                    bool t=((*(s+j)==*p)||(*p=='.'));
                    //cout<<"i: "<<i<<" j: "<<j<<" "<<t<<endl;
                    if(t==false)
                    {
                        m=false;
                        continue;
                    }
                }
                if(m==false)
                    break;
                else
                {
                    //cout<<"enter next: "<<i<<endl;
                    m=m&&isMatch(s+i,p+2);
                    if(m==true)
                        return true;
                }
            }
        }
        return false;
    }
    

};

   解法二:动态规划法递归

   dp的方法是第二遍回头作的时候写的。此时明显感到思路比之前清晰了不少。。。再次强调,dp最关键的是要搞清楚matrix的意义。就此题而言,很是清楚:dp[i][j]表示S的前i个字符与P的前j个字符匹配。字符串

  更新规则:分类考虑,包括p[j]是普通字符,‘.'字符以及'*'字符。前二者更新规则比较清晰;‘*’字符比较麻烦,要分为重复0次以及重复0次以上。代码以下:io

  

public class Solution {
    public boolean isMatch(String s, String p) {
        if(s==null||p==null)
            return false;
        int m=s.length()+1;
        int n=p.length()+1;
        boolean dp[][]=new boolean[m][n];
        dp[0][0]=true;
        for(int i=1;i<n;i++)
        {
            if(p.charAt(i-1)=='*')
            {
                if(dp[0][i-2]||dp[0][i-1])
                    dp[0][i]=true;
            }
        }
        for(int i=1;i<m;i++)
        {
            for(int j=1;j<n;j++)
            {
                char sc=s.charAt(i-1);
                char pc=p.charAt(j-1);
                if(pc=='.'||sc==pc)
                {
                    dp[i][j]=dp[i-1][j-1]?true:false;    
                }
                else if(pc=='*')
                {
                    char pre=p.charAt(j-2);
                    if(dp[i][j-2])
                    {
                        //repeat zero time
                        dp[i][j]=true;
                        continue;
                    }
                    if((pre=='.'||pre==sc)&&dp[i-1][j])
                    {
                        //repeat at least one time
                        dp[i][j]=true;
                        continue;
                    }
                }
            }
        }
        return dp[m-1][n-1];
    }
}

  上述代码中,重复0次和重复屡次的条件分开写实为了思路更清晰。由于重复0次是以行为参考,重复屡次是以列为参考。ast

  

  网上彷佛有人说用动态规划方法。DP一直是只知其一;不知其二,之后考虑再用DP解。class

相关文章
相关标签/搜索