请实现一个函数用来匹配包括 '.' 和 '*' 的正则表达式。模式中的字符 '.' 表示任意一个字符,而 '*' 表示它前面的字符能够出现任意次(包含 0 次)。java
在本题中,匹配是指字符串的全部字符匹配整个模式。例如,字符串 "aaa" 与模式 "a.a" 和 "ab*ac*a" 匹配,可是与 "aa.a" 和 "ab*a" 均不匹配。正则表达式
应该注意到,'.' 是用来当作一个任意字符,而 '*' 是用来重复前面的字符。这两个的做用不一样,不能把 '.' 的做用和 '*' 进行类比,从而把它当成重复前面字符一次。数组
/* 解这题须要把题意仔细研究清楚,反正我试了好屡次才明白的。 首先,考虑特殊状况: 1>两个字符串都为空,返回true 2>当第一个字符串不空,而第二个字符串空了,返回false(由于这样,就没法 匹配成功了,而若是第一个字符串空了,第二个字符串非空,仍是可能匹配成 功的,好比第二个字符串是“a*a*a*a*”,因为‘*’以前的元素能够出现0次, 因此有可能匹配成功) 以后就开始匹配第一个字符,这里有两种可能:匹配成功或匹配失败。但考虑到pattern 下一个字符多是‘*’, 这里咱们分两种状况讨论:pattern下一个字符为‘*’或 不为‘*’: 1>pattern下一个字符不为‘*’:这种状况比较简单,直接匹配当前字符。若是 匹配成功,继续匹配下一个;若是匹配失败,直接返回false。注意这里的 “匹配成功”,除了两个字符相同的状况外,还有一种状况,就是pattern的 当前字符为‘.’,同时str的当前字符不为‘\0’。 2>pattern下一个字符为‘*’时,稍微复杂一些,由于‘*’能够表明0个或多个。 这里把这些状况都考虑到: a>当‘*’匹配0个字符时,str当前字符不变,pattern当前字符后移两位, 跳过这个‘*’符号; b>当‘*’匹配1个或多个时,str当前字符移向下一个,pattern当前字符 不变。(这里匹配1个或多个能够当作一种状况,由于:当匹配一个时, 因为str移到了下一个字符,而pattern字符不变,就回到了上边的状况a; 当匹配多于一个字符时,至关于从str的下一个字符继续开始匹配) 以后再写代码就很简单了。 */
连接:https://www.nowcoder.com/questionTerminal/45327ae22b7b413ea21df13ee7d6429c?f=discussion
来源:牛客网
函数
当模式中的第二个字符不是“*”时:code
一、若是字符串第一个字符和模式中的第一个字符相匹配,那么字符串和模式都后移一个字符,而后匹配剩余的。字符串
二、若是 字符串第一个字符和模式中的第一个字符相不匹配,直接返回false。get
而当模式中的第二个字符是“*”时:io
若是字符串第一个字符跟模式第一个字符不匹配,则模式后移2个字符,继续匹配。若是字符串第一个字符跟模式第一个字符匹配,能够有3种匹配方式:class
一、模式后移2字符,至关于x*被忽略;di
二、字符串后移1字符,模式后移2字符;
三、字符串后移1字符,模式不变,即继续匹配字符下一位,由于*能够匹配多位;
这里须要注意的是:Java里,要时刻检验数组是否越界。
连接:https://www.nowcoder.com/questionTerminal/45327ae22b7b413ea21df13ee7d6429c?f=discussion 来源:牛客网 public class Solution { public boolean match(char[] str, char[] pattern) { if (str == null || pattern == null) { return false; } int strIndex = 0; int patternIndex = 0; return matchCore(str, strIndex, pattern, patternIndex); } public boolean matchCore(char[] str, int strIndex, char[] pattern, int patternIndex) { //有效性检验:str到尾,pattern到尾,匹配成功 if (strIndex == str.length && patternIndex == pattern.length) { return true; } //pattern先到尾,匹配失败 if (strIndex != str.length && patternIndex == pattern.length) { return false; } //模式第2个是*,且字符串第1个跟模式第1个匹配,分3种匹配模式;如不匹配,模式后移2位 if (patternIndex + 1 < pattern.length && pattern[patternIndex + 1] == '*') { if ((strIndex != str.length && pattern[patternIndex] == str[strIndex]) || (pattern[patternIndex] == '.' && strIndex != str.length)) { return matchCore(str, strIndex, pattern, patternIndex + 2)//模式后移2,视为x*匹配0个字符 || matchCore(str, strIndex + 1, pattern, patternIndex + 2)//视为模式匹配1个字符 || matchCore(str, strIndex + 1, pattern, patternIndex);//*匹配1个,再匹配str中的下一个 } else { return matchCore(str, strIndex, pattern, patternIndex + 2); } } //模式第2个不是*,且字符串第1个跟模式第1个匹配,则都后移1位,不然直接返回false if ((strIndex != str.length && pattern[patternIndex] == str[strIndex]) || (pattern[patternIndex] == '.' && strIndex != str.length)) { return matchCore(str, strIndex + 1, pattern, patternIndex + 1); } return false; } }