题目:请实现一个函数用来匹配包含’.‘和’‘的正则表达式。模式中的字符’.‘表示任意一个字符,而’'表示它前面的字符可以出现任意次(含0次)。在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串"aaa"与模式"a.a"和"abaca"匹配,但与"aa.a"及"ab*a"均不匹配。
解题思路:
这里匹配情况分两种:
- 模式中没有 *: 直接逐个匹配,’.'可以看作任意字符
- 模式中有 * :在第一个字符匹配,第二个字符是’*'的情况下,又可以分成三种情况:
①情况1:指向字符串的指针移动一次,指向模式串的指针移动两次
②情况2:指向字符串的指针移动一次,指向模式串的指针不动
③情况3:指向字符串的指针不动,指向模式串的指针移动两次
基于以上分析,java参考代码如下:
public class RegularExpressionsMatching {
public static boolean match(String str,String pattern){
if(str==null || pattern==null)
return false;
return matchCore(new StringBuilder(str),0,new StringBuilder(pattern),0);
}
//StringBuilder的作用:
public static boolean matchCore(StringBuilder str,Integer strIndex,StringBuilder pattern, Integer patternIndex){
//如果匹配串和模式串都匹配结束
if(strIndex==str.length() && patternIndex==pattern.length())
return true;
if(strIndex!=str.length() && patternIndex==pattern.length())
return false;
if(strIndex==str.length() && patternIndex!=pattern.length()) {
if(patternIndex+1<pattern.length()&&pattern.charAt(patternIndex+1)=='*')
return matchCore(str,strIndex,pattern,patternIndex+2);
else
return false;
}
//如果模式串的第二个字符不是*或者已经只剩一个字符了
if(patternIndex==pattern.length()-1|| pattern.charAt(patternIndex+1)!='*'){
if(pattern.charAt(patternIndex)=='.' || pattern.charAt(patternIndex)==str.charAt(strIndex))
return matchCore(str,strIndex+1,pattern,patternIndex+1);
else
return false;
}
//如果模式串的第二个字符是*
else{
if(pattern.charAt(patternIndex)=='.'||pattern.charAt(patternIndex)==str.charAt(strIndex))
return matchCore(str,strIndex+1,pattern,patternIndex)
||matchCore(str,strIndex+1,pattern,patternIndex+2)
||matchCore(str,strIndex,pattern,patternIndex+2);
else
return matchCore(str,strIndex,pattern,patternIndex+2);
}
}
public static void main(String[] args){
System.out.println(match("aaa","a.a"));//true
System.out.println(match("aaa","ab*ac*a"));//true
System.out.println(match("aaa","aa.a"));//false
System.out.println(match("aaa","ab*a"));//false
}
}
C++参考代码如下:
bool matchCore(const char* str, const char* pattern)
{
if (*str == '\0' && *pattern == '\0')
return true;
if (*str != '\0' && *pattern == '\0')
return false;
/*第二个字符是 '*' 的情况*/
if (*(pattern + 1) == '*')
{
if (*pattern == *str || (*pattern == '.' && *str != '\0'))
return matchCore(str + 1, pattern + 2) //情况1
|| matchCore(str + 1, pattern) //情况2
|| matchCore(str, pattern + 2); //情况3
else
return matchCore(str, pattern + 2);
}
if (*str == *pattern || (*pattern == '.' && *str != '\0'))
return matchCore(str + 1, pattern + 1);
return false;
}
bool match(const char* str, const char* pattern)
{
if (str == nullptr || pattern == nullptr)
return false;
return matchCore(str, pattern);
}
测试用例:
a.功能测试(模式字符串里包含普通字符:‘.’和‘*’;模式字符串和输入字符串匹配/不匹配)。
b.特殊输入测试(输入字符串和模式字符串时nullptr、空字符串)。