[Java]牛客网华为机试题目HJ71的递归解法

本文采用递归的方法,待匹配字符串是否匹配成功按照通配符字符串的最后一位分类讨论
华为机试题目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);
    }
}

提交结果如下图所示:

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
括号检查是指通过编程实现对一个字符串中的括号是否配对出现进行检查。例如,字符串"([{}])"中,括号是配对出现的,而字符串"([)]"中,括号是不配对的。 在华为中,括号检查是一道常见的编程题。通常可以通过栈(Stack)的方式进行实现。具体操作为,遍历字符串,当遇到左括号时将其压入栈顶,当遇到右括号时弹出栈顶,判断是否与当前右括号匹配。如果不匹配,则表示括号不配对,返回false;否则继续遍历。最后,如果栈为空,则表示所有左右括号都配对成功,返回true;否则表示还有括号未配对,返回false。 例如,对于字符串"([]{}())",栈的变化过程如下: 遍历字符"(",将其压入栈中。 遍历字符"[",将其压入栈中。 遍历字符"]",弹出栈顶"[",判断是否匹配,匹配,继续遍历。 遍历字符"{",将其压入栈中。 遍历字符"}",弹出栈顶"{",判断是否匹配,匹配,继续遍历。 遍历字符"(",将其压入栈中。 遍历字符")",弹出栈顶"(",判断是否匹配,匹配,继续遍历。 遍历结束,栈为空,括号检查合法,返回true。 如果字符串中存在不配对的括号,栈的最终状态不为空。例如,字符串"([]{}())]",栈的变化过程如下: 遍历字符"(",将其压入栈中。 遍历字符"[",将其压入栈中。 遍历字符"]",弹出栈顶"[",判断是否匹配,匹配,继续遍历。 遍历字符"{",将其压入栈中。 遍历字符"}",弹出栈顶"{",判断是否匹配,匹配,继续遍历。 遍历字符"(",将其压入栈中。 遍历字符")",弹出栈顶"(",判断是否匹配,匹配,继续遍历。 遍历字符"]",栈顶为"[",但与当前"]"不匹配,返回false。 因此,栈是解决括号检查的一种有效方式。此外,还可以使用归实现。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值