华为OD机考题(HJ71 字符串通配符)

前言

经过前期的数据结构和算法学习,开始以OD机考题作为练习题,继续加强下熟练程度。

描述

问题描述:在计算机中,通配符一种特殊语法,广泛应用于文件搜索、数据库、正则表达式等领域。现要求各位实现字符串通配符的算法。

要求:

实现如下2个通配符:

*:匹配0个或以上的字符(注:能被*和?匹配的字符仅由英文字母和数字0到9组成,下同)

?:匹配1个字符

注意:匹配时不区分大小写。

输入:

通配符表达式;

一组字符串。

输出:

返回不区分大小写的匹配结果,匹配成功输出true,匹配失败输出false

数据范围:字符串长度:1≤𝑠≤100 1≤s≤100

进阶:时间复杂度:𝑂(𝑛2) O(n2) ,空间复杂度:𝑂(𝑛) O(n)

输入描述:

先输入一个带有通配符的字符串,再输入一个需要匹配的字符串

输出描述:

返回不区分大小写的匹配结果,匹配成功输出true,匹配失败输出false

示例1

输入:

复制代码
te?t*.*
txt12.xls

输出:

复制代码
false

实现原理与步骤

  • 初始化

    • dp[0][0]表示空字符串和空模式匹配。
    • 如果模式p的字符是'*',则dp[0][j]的值取决于dp[0][j - 1],表示'*'可以匹配空字符串。
  • 填充DP数组

    • 遍历字符串s和模式p的所有字符。
    • 如果模式字符是'*',则dp[i][j]可以由两种情况决定:
      • dp[i - 1][j]'*'匹配一个或多个字符。
      • dp[i][j - 1]'*'匹配空字符串。
    • 如果模式字符是'?'或与字符串字符相等,则dp[i][j]dp[i - 1][j - 1]决定,表示这两个字符匹配。
  • 返回结果

    • 返回dp[sLen][pLen],表示字符串s和模式p的匹配结果。

此题为难度系数为中等略有不妥,另外需注意题干中?和*只能匹配数字和英文字母。

实现代码

java 复制代码
import java.util.Scanner;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        // 注意 hasNext 和 hasNextLine 的区别
        String p = in.nextLine();
        String s = in.nextLine();
        System.out.println(isMatch(s, p)); // 输出:true 或 false

    }

    public static boolean isMatch(String s, String p) {
        int sLen = s.length();
        int pLen = p.length();

        // 创建一个DP数组,dp[i][j]表示s的前i个字符和p的前j个字符是否匹配
        boolean[][] dp = new boolean[sLen + 1][pLen + 1];

        // 初始化
        dp[0][0] = true; // 空字符串和空模式是匹配的

        // 初始化首行,s为空,只有p全是'*'才能匹配
        for (int j = 1; j <= pLen; j++) {
            if (p.charAt(j - 1) == '*') {
                dp[0][j] = dp[0][j - 1];
            }
        }

        // 填充DP数组
        for (int i = 1; i <= sLen; i++) {
            for (int j = 1; j <= pLen; j++) {
                if (p.charAt(j - 1) == '*') {
                    // '*' 可以匹配任意字符串(包括空字符串)
                    //if(isNumOrWord(s.charAt(i-1))){
                    dp[i][j] = dp[i - 1][j] || dp[i][j - 1];
                    //}
                } else if ((p.charAt(j - 1) == '?' && isNumOrWord(s.charAt(i - 1))) ||
                           Character.toString(s.charAt(i - 1)).equalsIgnoreCase(Character.toString(
                                       p.charAt(j - 1)))) {
                    // '?' 可以匹配任意一个字符
                    dp[i][j] = dp[i - 1][j - 1];
                }
            }
        }

        return dp[sLen][pLen];
    }

    public static boolean isNumOrWord(char c) {
        if (c - 'a' >= 0 && c - 'a' <= 26) {
            return true;
        } else if (c - '0' >= 0 && c - '0' <= 9) {
            return true;
        }
        return false;
    }


}

1.QA:

相关推荐
CodeClimb1 天前
【华为OD-E卷-租车骑绿道 100分(python、java、c++、js、c)】
java·javascript·c++·python·华为od
CodeClimb1 天前
【华为OD-E卷-MVP争夺战 100分(python、java、c++、js、c)】
java·python·华为od
arnold663 天前
华为OD E卷(100分)34-转盘寿司
算法·华为od
CodeClimb3 天前
【华为OD-E卷-木板 100分(python、java、c++、js、c)】
java·javascript·c++·python·华为od
CodeClimb4 天前
【华为OD-E卷-寻找密码 100分(python、java、c++、js、c)】
java·python·华为od
枫叶丹44 天前
【HarmonyOS之旅】HarmonyOS开发基础知识(三)
华为od·华为·华为云·harmonyos
CodeClimb5 天前
【华为OD-E卷-简单的自动曝光 100分(python、java、c++、js、c)】
java·python·华为od
CodeClimb5 天前
【华为OD-E卷-最左侧冗余覆盖子串 100分(python、java、c++、js、c)】
java·python·华为od
星海拾遗6 天前
华为OD --- TLV解码
华为od
arnold666 天前
华为OD E卷(100分)31-敏感字段加密
算法·华为od