题解 | #字符串通配符#

字符串通配符

http://www.nowcoder.com/practice/43072d50a6eb44d2a6c816a283b02036

我的真的超级好理解,真的,而且修复了leetcode的bug。

import java.util.*;

public class Main {
    // 参考 leetcode 44 题
    public static boolean isMatch(String s, String p) {
        int m = s.length();
        int n = p.length();
        boolean[][] dp = new boolean[m + 1][n + 1];
        dp[0][0] = true;
        for (int i = 1; i <= n; i++) {
            if (p.charAt(i - 1) == '*') {
                dp[0][i] = true;
            } else {
                break;
            }
        }
        
        for (int i = 1; i <= m; i++) {
            for (int j = 1; j <= n; j++) {
                char ch = s.charAt(i - 1);
                // 注意:*和?处理的是字母和数字,所以要加判断
                if (p.charAt(j - 1) == '*' && (Character.isLetter(ch) || Character.isDigit(ch))) {
                    // ************ 千万要注意,这里一定要加上 dp[i - 1][j - 1],因为?的功能*同样拥有
                    dp[i][j] = dp[i][j - 1] || dp[i - 1][j] || dp[i - 1][j - 1];
                } else if (p.charAt(j - 1) == '?' && (Character.isLetter(ch) || Character.isDigit(ch))) {
                    dp[i][j] = dp[i - 1][j - 1];
                } else if (s.charAt(i - 1) == p.charAt(j - 1)) {
                    dp[i][j] = dp[i - 1][j - 1];
                }
            }
        }
        
        return dp[m][n];
    }

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while (in.hasNext()) {
            String pattern = in.nextLine();
            String str = in.nextLine();

            // 处理大写字符,防止比较的时候由于大写问题导致计算错误
            StringBuilder newS = new StringBuilder();
            for (int i = 0; i < str.length(); i++) {
                char ch = str.charAt(i);
                if (Character.isLetter(ch) && Character.isUpperCase(ch)) {
                    newS.append(Character.toLowerCase(ch));
                } else {
                    newS.append(ch);
                }
            }
            StringBuilder newP = new StringBuilder();
            for (int i = 0; i < pattern.length(); i++) {
                char ch = pattern.charAt(i);
                if (Character.isLetter(ch) && Character.isUpperCase(ch)) {
                    newP.append(Character.toLowerCase(ch));
                } else {
                    newP.append(ch);
                }
            }

            boolean ans = isMatch(newS.toString(), newP.toString());
            System.out.println(ans);
        }
    }
}
全部评论
字符串的大写转小写用一句话就可以了s1 = s1.toLowerCase();
4 回复 分享
发布于 2022-03-29 18:48
用的是动态规划
1 回复 分享
发布于 2022-03-29 18:47
10-31行看不懂啊
点赞 回复 分享
发布于 2022-03-16 19:33
dp[i][j] = dp[i - 1][j - 1];为啥用这样了?
点赞 回复 分享
发布于 2022-03-16 19:46
不懂原因
点赞 回复 分享
发布于 2022-03-23 15:20
24行为什么要加入dp[i-1][j-1]呀?dp[i-1][j-1]如果等于true的话,dp[i][j-1]不也就等于true了吗,进而dp[i][j]不是也就等于true了吗
点赞 回复 分享
发布于 2023-03-29 23:21 浙江
你这个问题太大了,*可以匹配0个和多个,你这里只考虑了匹配一个的情况,所以12345 123*这种你匹配不了,12345% 12345%*你也匹配不了
点赞 回复 分享
发布于 03-19 14:22 广东
public static boolean isMatch(String s, String p) { int m = s.length(); int n = p.length(); boolean[][] dp = new boolean[m + 1][n + 1]; dp[0][0] = true; for (int i = 1; i <= n; i++) { if (p.charAt(i - 1) == '*') { dp[0][i] = true; } else { break; } } for (int i = 1; i <= m; i++) { for (int j = 1; j <= n; j++) { char ch = s.charAt(i - 1); // 注意:*和?处理的是字母和数字,所以要加判断 if (p.charAt(j - 1) == '*') { dp[i][j] = dp[i][j - 1] || ((dp[i - 1][j] || dp[i - 1][j - 1]) && Character.isLetterOrDigit(ch)); } else if (p.charAt(j - 1) == '?' && Character.isLetterOrDigit(ch) ) { dp[i][j] = dp[i - 1][j - 1]; } else if (s.charAt(i - 1) == p.charAt(j - 1)) { dp[i][j] = dp[i - 1][j - 1]; } } } return dp[m][n]; } public static void main(String[] args) { Scanner in = new Scanner(System.in); while (in.hasNext()) { String pattern = in.nextLine().toLowerCase(); String str = in.nextLine().toLowerCase(); boolean ans = isMatch(str, pattern); System.out.println(ans); } }
点赞 回复 分享
发布于 03-19 15:00 广东

相关推荐

6 1 评论
分享
牛客网
牛客企业服务