前言
经过前期的数据结构和算法学习,开始以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;
}
}