牛客网 字符串通配符

简介: 牛客网 字符串通配符

做题链接:字符串通配符__牛客网 (nowcoder.com)

要求:实现如下2个通配符(不区分大小写):


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

? :匹配1个字符

输入:通配符表达式;一组字符串。


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


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


示例:


pq
pppq
false
**Z
0QZz
true
?*Bc*?
abcd
true
h*?*a
h#a
false
p*p*qp**pq*p**p***ppq
pppppppqppqqppqppppqqqppqppqpqqqppqpqpppqpppqpqqqpqqp
false


做题思路 : dp 问题   使用二维数组解决问题

假设两个字符串分别是   ABCD      * BC * ?   ,那么我们就可以画出如下图

1. 为什么多一行为 null?    ---->  因为字符串可能为空  其实这就是一点一点匹配的过程


8ce89b7b7c8a4633aef57b1e3d3ae4ef.png

 2. 先填充为 null 的部分


a8e757ad4c664caba68d4330dc194879.png

3. 匹配剩余地方


我们可以根据 横轴的字母来分类判断是否为 T


 *   :左边 || 上面 || 左上角

 ?  :  当前位置可以匹配     且左上角为 T  就为 T

 字母/数字:当前位置可以匹配,左上角 为 T 就为 T

得到下图 ,我们可以看到最后一个 为 T  那么也就代表  这两个字符串可以匹配。


3e11878e92304137bb95e8fa50fc0a88.png


最终代码:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        Scanner scanner = new Scanner(System.in);
        String str1 = scanner.nextLine().toLowerCase();//带通配符的字符串
        String str2 = scanner.nextLine().toLowerCase();//不带通配符的字符串
        boolean ret = isMatching(str1, str2);
        System.out.println(ret);
    }
        public static boolean isMatching(String s1, String s2) {
        boolean[][] arr = new boolean[s2.length() + 1][s1.length() + 1];
        //我们使用 0 代表 false   1 代表 true
        //1.首先把第一行和第一列搞定
        //    第一行:
        arr[0][0] = true;
        for (int i = 1; i <= s1.length(); i++) {
            char ch = s1.charAt(i - 1);
            if (ch == '*') {
                arr[0][i] = arr[0][i - 1];
            } else {
                arr[0][i] = false;
            }
        }
        //    第一列
        for (int i = 1; i <= s2.length(); i++) {
            char ch = s2.charAt(i - 1);
            if (ch == '*') {
                arr[i][0] = arr[i - 1][0];
            } else {
                arr[i][0] = false;
            }
        }
        //2.填充其他部分
        for (int i = 1; i <= s2.length(); i++) {
            for (int j = 1; j <= s1.length(); j++) {
                char ch = s1.charAt(j - 1);
                //①判断是*的情况
                if (ch == '*' && isOk(s2.charAt(i - 1))){
                    arr[i][j] = arr[i - 1][j] || arr[i][j - 1] || arr[i-1][j-1];
                }
                //②判断是 ? 的情况
                else if (ch == '?' && isOk(s2.charAt(i - 1))) {
                    arr[i][j] = arr[i - 1][j - 1];
                }
                //③不是通配符的情况
                else{
                    if (ch == s2.charAt(i - 1) && arr[i - 1][j - 1]) {
                        arr[i][j] = true;
                    } else {
                        arr[i][j] = false;
                    }
                }
            }
        }
        return arr[s2.length()][s1.length()];
    }
    public static boolean isOk(char ch) {
        return ch >= 'a' && ch <= 'z' || ch >= '0' && ch <= '9' || ch >= 'A' && ch <= 'Z';
    }
}


相关文章
|
2月前
|
测试技术
leetcode-1576:替换所有的问号
leetcode-1576:替换所有的问号
37 1
|
2月前
|
Java
每日一刷《剑指offer》字符串篇之正则表达式匹配
每日一刷《剑指offer》字符串篇之正则表达式匹配
56 0
每日一刷《剑指offer》字符串篇之正则表达式匹配
|
11月前
|
算法 C语言 C++
LeetCode每日一题 1023. 驼峰式匹配 --双指针
本题挺容易想到的,难得是如何处理特殊的情况.
61 0
LeetCode每日一题 1023. 驼峰式匹配 --双指针
|
算法 安全 Swift
LeetCode - #44 通配符匹配
不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。如果大家有建议和意见欢迎在文末留言,我们会尽力满足大家的需求。
LeetCode - #44 通配符匹配
|
JavaScript
剑指offer 18. 正则表达式匹配
剑指offer 18. 正则表达式匹配
44 0
【刷题】无重复字符的最长子串
【刷题】无重复字符的最长子串
【刷题】无重复字符的最长子串
|
算法
LeetCode 43字符串相乘&44通配符匹配
给定两个以字符串形式表示的非负整数 num1 和 num2,返回 num1 和 num2 的乘积,它们的乘积也表示为字符串形式。
91 0
LeetCode 43字符串相乘&44通配符匹配
|
索引
Leetcode每日一题——找到字符串中所有字母异位词
给定两个字符串 s 和 p,找到 s 中所有 p 的 异位词 的子串,返回这些子串的起始索引。不考虑答案输出的顺序。
71 0
|
机器学习/深度学习 算法
每日算法刷题Day10-字符串最大跨距、最长公共字符串后缀
⭐每日算法题解系列文章旨在精选重点与易错的算法题,总结常见的算法思路与可能出现的错误,与笔者另一系列文章有所区别,并不是以知识点的形式提升算法能力,而是以实战习题的形式理解算法,使用算法。
204 0
AcWing 768. 忽略大小写比较字符串大小
AcWing 768. 忽略大小写比较字符串大小
74 0
AcWing 768. 忽略大小写比较字符串大小