Regular Expression Matching

来源:互联网 发布:黑白照片的魅力 知乎 编辑:程序博客网 时间:2024/05/29 09:54

原题:

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") → falseisMatch("aa","aa") → trueisMatch("aaa","aa") → falseisMatch("aa", "a*") → trueisMatch("aa", ".*") → trueisMatch("ab", ".*") → trueisMatch("aab", "c*a*b") → true

即判断给定字符串是否符合正则表达式。这里正则表达式包括符号'.','*',前者表示可以和任意单个字符匹配,后者表示后者前面的字符可以匹配0到多个。两者放到一起,代表可以匹配任何长度的任何字符。


思考过程:

很难确定'*'和多少个字符匹配合适,一筹莫展,看了别人的博客,受到启发。用递归函数,动态规划思想,遍历所有可能个数的字母和'*'匹配,直至匹配成功,否则返回false。


解题思路:

详情看代码注释。这里要注意字符索引越界问题。在s遍历结束后要继续判断,因为如果p剩下"a*"这样的字符,它们也是匹配的。

public boolean isMatch(String s, String p){        if (p.isEmpty()) return s.isEmpty();//递归结束的标志        if (p.length() == 1) return ((s.length() == 1 && p.charAt(0) == '.') || p.equals(s));//防止后面p,charAt(1)越界,同时也是递归结束的标志        if (p.charAt(1) == '*') return (isMatch(s,p.substring(2)) || (!s.isEmpty() &&(s.charAt(0) == p.charAt(0) || p.charAt(0) == '.') && (isMatch(s.substring(1),p))));//第二个字母为'*'的情况:要么在p中越过p.charAt(0),p.charAt(1),要么首字母匹配情况下,p不变,s匹配下一个字母。        else if (!s.isEmpty() && (s.charAt(0) == p.charAt(0) || p.charAt(0) == '.')) return isMatch(s.substring(1), p.substring(1));//首字母匹配,而且第二个字母不是'*',递归            else return false;//第二个字母不是'*'而且首字母不匹配,返回false    }