[LeetCode.10] 写一个正则表达式匹配

首先,抛开.*不管,如何递归地判断两个字符串相等呢?

class Solution {
    bool isMatch(string s, string p)     {
        int slen = s.length();
        int plen = p.length();

        if (slen == 0 && plen == 0)             return true;

        char c0 = getChar(s, 0);
        char p0 = getChar(p, 0);

        if (match(c0, p0))         {
            return isMatch(s.substr(1), p.substr(1));
        }
        return false;
    }
    //判断两个字符是否相等
    bool match(char a, char b)     {
        return a == b;
    }

    //为什么要这个函数呢,主要是为了统一处理下标越界的问题
    //如果越界了,直接返回0即可
    char getChar(string s, int p)     {
        if (s.length() > p)         {
            return s[p];
        }
        return 0;
    }
}

根据题意,.可根任何字符匹配,那么match方法就要改成:

//判断两个字符是否相等
bool match(char a, char b) {
    return a == b || b == '.';
}

由于*对前一个字符有副作用,故需要对*进行特殊判断。尤其是[任意字符]*可以匹配任意长度的字符串,包括空串。因此,每次处理isMatch时,都要向后探一下接下来是否有*

  • 如果有*,则枚举其匹配所有可能性,只要有一个返回true,则返回true
  • 如果没有*, 上述代码的逻辑则不需要变

最终代码:

class Solution 
{
public:
    bool isMatch(string s, string p) 
    {
        int slen = s.length();
        int plen = p.length();


        if (slen == 0 && plen == 0) 
            return true;


        char c0 = getChar(s, 0);
        char p0 = getChar(p, 0), p1 = getChar(p, 1);


        if (match(c0, p0) || p1 == '*') 
        {
            if (p1 != '*') 
            {
                if (slen == 0) 
                    return false;
                return isMatch(s.substr(1), p.substr(1));
            }
            // if p1 is *, * means 0 ~ n
            int i = 0;
            bool ret = isMatch(s.substr(0), p.substr(2)); // try 0
            if (ret) 
                return ret;
            while (i < slen && match(getChar(s, i), p0)) 
            {
                ret = isMatch(s.substr(i+1), p.substr(2)); // try for every available position
                if (ret) 
                    return ret;
                i++;
            }
        }


        return false;
    }


    bool match(char a, char b) 
    {
        return a == b || b == '.';
    }


    char getChar(string s, int p) 
    {
        if (s.length() > p) 
        {
            return s[p];
        }
        return 0;
    }
};

此算法实际运行复杂度较高,leetcode上15.44%,但是个中知识值得细细咀嚼。

整理自:https://segmentfault.com/a/1190000000453572

如有不当之处,请联系我:[email protected]

猜你喜欢

转载自blog.csdn.net/weixin_39460182/article/details/80190260