java字符串匹配dp_字符串匹配问题

本文介绍了两种实现正则表达式匹配的算法:递归解法与动态规划解法。递归方法通过逐字符对比来判断字符串是否符合正则表达式的规则;动态规划方法则利用二维数组记录中间结果,避免重复计算,提高效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

递归解法 import java.util.*;

public class Main {

//isValid

public static boolean isValid(char[] s, char[] e) {

for(int i = 1; i < e.length; i++) {

if (e[i] == '*' && e[i - 1] == '*')

return false;

}

return true;

}

public static boolean judge(char[] s, char[] e, int si, int ei) {

if (ei == e.length) {

return si == s.length;

}

if (ei + 1 == e.length || e[ei + 1] != '*') {

return si != s.length && (e[ei] == s[si] || e[ei] == '.')

&& judge(s, e, si + 1, ei + 1);

}

while (si != s.length && (e[ei] == s[si] || e[ei] == '.')) {

if (judge(s, e, si, ei + 2)) {

return true;

}

si ++;

}

return judge(s, e, si, ei + 2);

}

public static void main(String[] args) {

Scanner sc = new Scanner(System.in);

char[] s = sc.nextLine().toCharArray();

char[] e = sc.nextLine().toCharArray();

sc.close();

if (!isValid(s, e)) {

System.out.println("NO");

return;

}

if (!judge(s, e, 0, 0)) {

System.out.println("NO");

} else {

System.out.println("YES");

}

}

}

动态规划解法 import java.util.*;

public class Main {

public static boolean isValid(char[] s, char[] e) {

for (int i = 0; i < s.length; i++) {

if (s[i] == '*' || s[i] == '.') {

return false;

}

}

for (int i = 0; i < e.length; i++) {

if (e[i] == '*' && (i == 0 || e[i - 1] == '*')) {

return false;

}

}

return true;

}

public static boolean isMatchDP(String str, String exp) {

if (str == null || exp == null) {

return false;

}

char[] s = str.toCharArray();

char[] e = exp.toCharArray();

if (!isValid(s, e)) {

return false;

}

boolean[][] dp = initDPMap(s, e);

for (int i = s.length - 1; i > -1; i--) {

for (int j = e.length - 2; j > -1; j--) {

if(e[j + 1] != '*') {

dp[i][j] = (s[i] == e[j] || e[j] == '.') && dp[i + 1][j + 1];

} else {

int si = i;

while (si != s.length && (s[si] == e[j] || e[j] == '.')) {

if (dp[si][j + 2]) {

dp[i][j] = true;

break;

}

si++;

}

if (dp[i][j] != true) {

dp[i][j] = dp[si][j + 2];

}

}

}

}

return dp[0][0];

}

public static boolean[][] initDPMap(char[] s, char[] e) {

int slen = s.length;

int elen = e.length;

boolean[][] dp = new boolean[slen + 1][elen + 1];

dp[slen][elen] = true;

for (int j = elen - 2; j > -1; j -= 2) {

if (e[j] != '*' && e[j + 1] == '*') {

dp[slen][j] = true;

} else {

break;

}

}

if (slen > 0 && elen > 0) {

if ((e[elen - 1] == '.' || s[slen - 1] == e[elen - 1])) {

dp[slen - 1][elen - 1] = true;

}

}

return dp;

}

public static void main(String[] args) {

Scanner sc = new Scanner(System.in);

String str = sc.nextLine();

String exp = sc.nextLine();

if (isMatchDP(str, exp)) {

System.out.println("YES");

} else {

System.out.println("NO");

}

}

}

字符串匹配问题可以使用动态规划法进行解决。具体来说,可以使用一个二维数组dp[i][j]表示文本串中前i个字符与模式串中前j个字符是否匹配。其中,dp[0][0]表示两个空串匹配dp[i][0]表示空模式串与任何文本串都匹配dp[0][j]则表示文本串为空,只有当模式串中前j个字符均为*时才为匹配。 状态转移方程如下: 1. 当模式串第j个字符是*时: dp[i][j] = dp[i][j-1] || dp[i-1][j] 解释:*可以表示空字符或者匹配一个或多个字符。dp[i][j-1]表示*匹配0个字符,dp[i-1][j]表示*匹配一个或多个字符。 2. 当模式串第j个字符不是*时: dp[i][j] = dp[i-1][j-1] && (text[i-1] == pattern[j-1] || pattern[j-1] == '?') 解释:当模式串第j个字符不是*时,只有当文本串中第i个字符与模式串中第j个字符相同或者模式串中第j个字符为?时才能匹配。 最终的匹配结果为dp[text_len][pattern_len],其中text_len和pattern_len分别为文本串和模式串的长度。 以下是使用Java语言实现字符串匹配问题的动态规划法的示例代码: ```java public class StringMatch { public static boolean isMatch(String text, String pattern) { int text_len = text.length(); int pattern_len = pattern.length(); // 初始化dp数组 boolean[][] dp = new boolean[text_len+1][pattern_len+1]; dp[0][0] = true; // 处理dp数组的第一行 for (int j = 1; j <= pattern_len; j++) { if (pattern.charAt(j-1) == '*') { dp[0][j] = dp[0][j-1]; } } // 处理dp数组的其余部分 for (int i = 1; i <= text_len; i++) { for (int j = 1; j <= pattern_len; j++) { if (pattern.charAt(j-1) == '*') { dp[i][j] = dp[i][j-1] || dp[i-1][j]; } else { dp[i][j] = dp[i-1][j-1] && (text.charAt(i-1) == pattern.charAt(j-1) || pattern.charAt(j-1) == '?'); } } } // 返回匹配结果 return dp[text_len][pattern_len]; } public static void main(String[] args) { Scanner sc = new Scanner(System.in); System.out.print("请输入文本串:"); String text = sc.nextLine(); System.out.print("请输入模式串:"); String pattern = sc.nextLine(); if (isMatch(text, pattern)) { System.out.println("匹配成功!"); } else { System.out.println("匹配失败!"); } } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值