本文采用递归的方法,待匹配字符串是否匹配成功按照通配符字符串的最后一位分类讨论
华为机试题目HJ71链接如下:
https://www.nowcoder.com/exam/oj?page=1&pageSize=50&search=71&tab=名企真题&topicId=37
public class HJ71 {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
//匹配不区分大小写,先将两个字符串的字母全变成小写
String str1 = scan.nextLine().toLowerCase();
String str2 = scan.nextLine().toLowerCase();
char[] arr1 = str1.toCharArray();
char[] arr2 = str2.toCharArray();
boolean result = stringMarch(arr1, arr2, arr1.length, arr2.length);
System.out.println(result);
}
//arr1是通配符字符数组,arr2是待匹配字符数组
//arr1(i)表示索引从0开始的长度为i的arr1子数组
//arr2(j)表示索引从0开始的长度为j的arr2子数组
public static boolean stringMarch(char[] arr1, char[] arr2, int i, int j) {
//1.arr1(0)的最后一位没有字符,此处为递归的出口
//当arr2(j)长度为0时与arr1(0)匹配成功,返回true
//当arr2(j)长度不为0时与arr1(0)匹配失败,返回false
if (i == 0) {
return j == 0;
}
//2.arr1(i)最后一位是'*'
else if (arr1[i - 1] == '*') {
//当arr1(i - 1)与arr2(j)匹配成功时,'*'匹配到0个字符
boolean b1 = stringMarch(arr1, arr2, i - 1, j);
//当j > 0时,arr1(i)与arr2(j - 1)匹配成功且'*'与arr2[j - 1]匹配成功时,'*'至少匹配到1个字符
//j > 0必须放在最前面,且与其他表达式使用短路与或者短路或连接,不然可能会发生数组下标越界
//j == 0就是上一种情况,'*'会匹配到0个字符
boolean b2 = j > 0 && isMarch(arr2[j - 1]) && stringMarch(arr1, arr2, i, j - 1);
//只要有一种情况匹配成功就表示arr1(i)与arr2(j)匹配成功,此时'*'匹配到0个以上的字符
return b1 || b2;
}
//3.arr1(i)最后一位是'?'
else if (arr1[i - 1] == '?') {
//当j > 0时,'?'匹配到一个字符且arr1(i - 1)与arr2(j - 1)匹配成功,则表示arr1(i)与arr2(j)匹配成功
return j > 0 && isMarch(arr2[j - 1]) && stringMarch(arr1, arr2, i - 1, j - 1);
}
//4.arr1(i)最后一位不为空,并且是'*'和'?'以外的字符
else {
//当j > 0时,arr1[i - 1]与arr1[j - 1]相等且arr1(i - 1)与arr2(j - 1)匹配成功,则表示arr1(i)与arr2(j)匹配成功
return j > 0 && arr1[i - 1] == arr2[j - 1] && stringMarch(arr1, arr2, i - 1, j - 1);
}
}
public static boolean isMarch(char c) {
return Character.isLetter(c) || Character.isDigit(c);
}
}
提交结果如下图所示: