正则表达式匹配算法

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

解决思路:
解决该问题的关键在于将匹配的情况考虑全面。加入 ‘*’ 这个符号将导致问题变得复杂,所以分情况讨论 ‘*’ 带来的影响。首先, ‘*’ 作用于某一个字符的后一位,这决定了我们在分析匹配情况时每次考虑模式串里的相邻两个字符。

  • 假如,第二个字符不是 ‘*’ ,则比较第一个字符和当前的字符串的字符是否相同即可(这里相等的情况还包括模式串的当前第一个字符是 ‘.’)。若相同,则字符串与模式串都后移一位,然后比较后面的子串是否匹配;若不同,直接说明二者不匹配。

  • 假如,第二个字符是 ‘*’ ,再分两种情况讨论:

    • 模式串当前两个字符中第一个字符与字符串当前字符不相同,则将模式串当前字符后移两位,字符串当前字符位置不变,再比较是否匹配。例:b 与 a* b 匹配,实际上a*的数目是0,这种情况。

    • 模式串当前两个字符中第一个字符与字符串当前字符相同,则会有三种情况:

      • 将模式串后移两位,字符串当前位置不变,然后比较后面子串是否匹配。例:b 与 a* b 匹配,实际上a*的数目是0,这种情况。
      • 将模式串后移两位,字符串当前位置后移一位,然后比较后面子串是否匹配。例:ab 与 a* b 匹配,实际上a的数目是1,这种情况。
      • 模式串当前位置不变,字符串当前位置后移一位,然后比较后面子串是否匹配。例:aa 与 a* b 匹配,实际上a的数目大于1,这种情况。

C++代码:
分情况递归即可解决上述问题。

class Solution {
public:
    bool match(char* str, char* pattern)
    {
        if(str == NULL || pattern == NULL)
            return false;
        return matchCore(str, 0, pattern, 0);
    }
    bool matchCore(char* str, int strIndex, char* pattern, int patternIndex)
    {
    	// 字符串与模式串同时读取完毕,则匹配完成,匹配成功
        if(strIndex == strlen(str) && patternIndex == strlen(pattern))
            return true;
        // 字符串未读取完毕,模式串已被读取完毕,则匹配失败
        if(strIndex != strlen(str) && patternIndex == strlen(pattern))
            return false;
            
        // 模式串当前不能选取两个字符,则仅比较当前字符即可
        if(patternIndex + 1 == strlen(pattern))
        {
            if(strIndex != strlen(str) && (str[strIndex] == pattern[patternIndex] || pattern[patternIndex] == '.'))
                return matchCore(str, strIndex + 1, pattern, patternIndex + 1);
            else
                return false;
        }
        // 模式串当前能选取两个字符
        else
        {
        	// 模式串当前第二个字符为'*'
            if(pattern[patternIndex+1] == '*')
            {
            	// 模式串当前第一个字符与字符串相同
                if(strIndex != strlen(str) && (str[strIndex] == pattern[patternIndex] || pattern[patternIndex] == '.'))
                {
                	// 思路分析阐述的三种情况,哪一种成功匹配都说明二者可以匹配,用或连接
                    return (matchCore(str, strIndex, pattern, patternIndex + 2) || 
                            matchCore(str, strIndex + 1, pattern, patternIndex + 2) || 
                            matchCore(str, strIndex + 1, pattern, patternIndex));
                }
                // 模式串当前第一个字符与字符串不同
                else
                {
                    return matchCore(str, strIndex, pattern, patternIndex + 2);
                }
            }
            // 模式串当前第二个字符不为'*'
            else
            {
                if(str[strIndex] == pattern[patternIndex] || pattern[patternIndex] == '.')
                    return matchCore(str, strIndex + 1, pattern, patternIndex + 1);
                else
                    return false;
            }
        }
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值