参考自:《剑指Offer——名企面试官精讲典型编程题》
题目:正则表达式匹配
请实现一个函数用来匹配包含’.’和’*’的正则表达式。模式中的字符’.’表示任意一个字符,而’*’表示它前面的字符可以出现任意次(含0次)。在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串”aaa”与模式”a.a”和”ab*ac*a”匹配,但与”aa.a”及”ab*a”均不匹配。
主要思路:
分四种情况:
1.字符串的当前字符和模式的当前字符不匹配:返回false。
2.模式的当前字符为’.’或者与字符串的当前字符一样:继续匹配剩余的字符串和模式。
3.模式的下一个字符为’*’且当前字符匹配,则有两种选择:
1)字符串不动;模式向后移动2个字符(相当于忽略’*’和它前面的字符,因为’*’可以匹配0个字符)。
2)字符串后移1个字符;模式可以保持不变,或者模式向后移动2个字符。
4.模式的下一个字符为’*’且当前字符不匹配,则字符串不动,模式向后移动2个字符。
关键点:’*’可以匹配0个或多个字符
时间复杂度:O(n)
public class RegularExpression
{
private static char[] str;
private static char[] pattern;
public static void main(String[] args)
{
String inStr = "aaa";
String inPattern = "aa*";
String inStr1 = "aaa";
String inPattern1 = "aa.a";
boolean result1 = match(inStr.toCharArray(), inPattern.toCharArray()); //true
boolean result2 = match(inStr1.toCharArray(), inPattern1.toCharArray()); //false
System.out.println(result1);
System.out.println(result2);
}
private static boolean match(char[] inStr, char[] inPattern)
{
if (inStr == null || inPattern == null) return false;
str = inStr;
pattern = inPattern;
return matchRegular(0, 0);
}
private static boolean matchRegular(int strIndex, int patternIndex)
{
//字符和模式全部匹配
if (str.length == strIndex && pattern.length == patternIndex)
{
return true;
}
if ((str.length != strIndex && pattern.length == patternIndex))
{
return false;
}
//模式的下一个字符是‘*’
if (patternIndex < pattern.length - 1 && pattern[patternIndex + 1] == '*')
{
//当前字符匹配
if (strIndex < str.length && (pattern[patternIndex] == str[strIndex]
|| pattern[patternIndex] == '.'))
{
return matchRegular(strIndex + 1, patternIndex + 2) //字符串和模式都移动
|| matchRegular(strIndex + 1, patternIndex) //字符串移动,模式不动
|| matchRegular(strIndex, patternIndex + 2); //字符串不动,模式移动
} else
{
return matchRegular(strIndex, patternIndex + 2); //字符串不动,模式移动
}
}
//当前字符和模式的字符匹配
if (strIndex < str.length && (pattern[patternIndex] == str[strIndex]
|| pattern[patternIndex] == '.'))
{
return matchRegular(strIndex + 1, patternIndex + 1); //模式和字符串都移动
}
return false;
}
}