做题链接:字符串通配符__牛客网 (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? ----> 因为字符串可能为空 其实这就是一点一点匹配的过程
2. 先填充为 null 的部分
3. 匹配剩余地方
我们可以根据 横轴的字母来分类判断是否为 T
* :左边 || 上面 || 左上角
? : 当前位置可以匹配 且左上角为 T 就为 T
字母/数字:当前位置可以匹配,左上角 为 T 就为 T
得到下图 ,我们可以看到最后一个 为 T 那么也就代表 这两个字符串可以匹配。
最终代码:
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'; } }