面试题19
请实现一个函数用来匹配包括'.'和'*'的正则表达式。模式中的字符'.'表示任意一个字符,而'*'表示它前面的字符可以出现任意次(包含0次)。 在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串"aaa"与模式"a.a"和"ab*ac*a"匹配,但是与"aa.a"和"ab*a"均不匹配
解析:本题用java写要考虑数组越界的问题,然后分为几种情况去讨论
首先说跳出递归的条件:
1. 当str和pattern都到了末尾,那就说明前面匹配成功,返回true
2. 当pattern已经到达末尾,而str没有匹配完,就说明str串长,匹配失败,返回false
3. 当str到达末尾,而pattern没有到达末尾
1)判断pattern当前不为*并且后面也不是*的情况,遍历pattern后面的所有,如果有这种情况就返回false(因为str已经到末尾,就需要pattern后面的字符串与*相互抵消才可以匹配成功)
2)否则后面字符串可以抵消,返回true
然后我们讨论边界的匹配情况:
就是判断当前pattern的位置的下一个到达串的末尾,那么如果当前的str与pattern相等或者pattern为.的话,就说明匹配成功,否则匹配失败
(这个放在前面说,是因为我们后面讨论的情况需要判断pattern当前位置的下一个是否为*,对其进行分类讨论)
最后讨论如何进行分类:
我们考虑pattern当前的下一个字符是否为*,对其进行分类讨论
1.下一个不为*,这种情况比较简单,只需要判断当前是否相等就可以
1)如果当前pattern和str匹配(包括pattern为.的情况),则,pattern和str分别向下一个位置移动
2)如果当前匹配不成功,则的返回false
2.pattern下一个字符为*(因为前面已经考虑下一个是否越界的情况,所以这里不需要考虑是否越界了)
那么也得进行分类讨论,就是当前字符是否匹配
1)当前字符匹配成功(包括pattern为.的情况),那么也同样分为二种情况:
(1)str向后移动一位,pattern不动(类似str=aaa,pattern=a*的情况,第一个a为当前位置)
(2)str不动,pattern向后移动二位(类似str = ab ,pattern =a*ab的情况,第一个a为当前位置)
2)当前字符匹配不成功,那么*表示的就相当于当前字符出现0次,所以str不动,pattern向后移动二位
import java.util.*;
public class N19 {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String s = in.nextLine();
String p = in.nextLine();
char str[] = s.toCharArray();
char pattern[] = p.toCharArray();
if(str==null||pattern==null)
System.out.println("false");
System.out.println(String.valueOf(M(str,pattern,0,0)));
}
private static boolean M(char str[],char pattern[],int i,int j){
if(i==str.length&&j==pattern.length)
return true;
if(i!=str.length&&j==pattern.length)
return false;
if(i==str.length&&j!=pattern.length){//当i在字符串尾,j没在模式串尾,
while(j!=pattern.length){
if(pattern[j]!='*'&&(j+1>=pattern.length||pattern[j+1]!='*')){
return false;
}
j++;
}
return true;
}
if(j+1==pattern.length){ //判断边界
if(str[i]==pattern[j]||pattern[j]=='.')
return M(str,pattern,i+1,j+1);
else
return false;
}
if(pattern[j+1]!='*'&&(str[i]==pattern[j]||pattern[j]=='.'))
return M(str,pattern,i+1,j+1);
if(pattern[j+1]=='*'&&(str[i]==pattern[j]||pattern[j]=='.'))
return M(str,pattern,i+1,j)||M(str,pattern,i,j+2);
if(pattern[j+1]=='*'&&str[i]!=pattern[j])
return M(str,pattern,i,j+2);
return false;
}
}