剑指Offer-52.正则表达式匹配(C++/Java)

题目:

请实现一个函数用来匹配包括'.'和'*'的正则表达式。模式中的字符'.'表示任意一个字符,而'*'表示它前面的字符可以出现任意次(包含0次)。 在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串"aaa"与模式"a.a"和"ab*ac*a"匹配,但是与"aa.a"和"ab*a"均不匹配

分析:

我们先分析匹配时,模式中的字符的下一个是*的情况,此时还会分成两种情况,

  一种是当前字符串中的字符和模式中的字符相同,或者模式中的字符是‘.’,也就是a和a* 或者 a和.*,此时我们有三条策略继续匹配,

    一种是认为a后面可能还有a,也就是*代表多个字符,所以匹配字符串字符的下一个字符和当前模式的字符。

    一种是认为a已经可以和当前模式的字符匹配上了,也就是*认为是1个字符,所以匹配字符串字符的下一个字符和当前模式的字符的下两个(a*匹配成功)。

    或者是将*当成0个字符,所以匹配字符串的当前字符和当前模式的字符的下两个(a*和空字符匹配成功)。

    这三种情况的结果取或,因为有一种匹配成功,就算匹配了。b

  如果前字符串中的字符和模式中的字符不相同,也就是(a和b*)这种情况,那么就匹配字符串的当前字符和当前模式的字符的下两个(b*和空字符匹配成功)。

如果模式中的字符的下一个不是*,也会分两种情况。

  一种是当前字符串中的字符和模式中的字符相同或模式中的字符是‘.’,也就是a和a或a和.这种,我们可以直接去匹配字符串和模式字符串的下一个字符。

  另一种情况就是当前的字符是不同的,那么就直接返回错误即可。

注意java要时刻判断数组越界问题。

程序:

C++

class Solution {
public:
    bool match(char* str, char* pattern)
    {
        if(*str == '\0' && *pattern == '\0')
            return true;
        if(*str != '\0' && *pattern == '\0')
            return false;
        if(*(pattern+1) == '*'){
            //a  a* || a .*
            if(*str == *pattern || (*pattern == '.' && *str != '\0')){
                return match(str+1, pattern) || match(str, pattern+2) || match(str+1, pattern+2);
            }
            //a b*
            else{
                return match(str, pattern+2);
            }
        }
        else{
            //a a || a .
            if(*str == *pattern || (*pattern == '.' && *str != '\0')){
                return match(str+1, pattern+1);
            }
            //a b
            else{
                return false;
            }

        }
    }
};

Java

public class Solution {
    public boolean match(char[] str, char[] pattern)
    {
        if(str == null || pattern == null)
            return false;
        return matchHelper(str, pattern, 0, 0);
    }
    public static boolean matchHelper(char[] str, char[] pattern, int i, int j)
    {
        if(i == str.length && j == pattern.length)
            return true;
        if(i != str.length && j == pattern.length)
            return false;
        if(j+1 < pattern.length && pattern[j+1] == '*') {
            if((i != str.length && pattern[j] == str[i]) || (pattern[j] == '.' && i != str.length)) {
                return matchHelper(str, pattern, i+1, j) ||
                        matchHelper(str, pattern, i, j+2) ||
                        matchHelper(str, pattern, i+1, j+2);
            }else {
                return matchHelper(str, pattern, i, j+2);
            }
        }else {
            if((i != str.length && pattern[j] == str[i]) || (pattern[j] == '.' && i != str.length)) {
                return matchHelper(str, pattern, i+1, j+1); 
            }else {
                return false;
            }
        }
    }
}
posted @ 2019-12-24 17:08  silentteller  阅读(384)  评论(0编辑  收藏  举报