PHP实现求解最长公共子串问题的方法

1. 最长公共子串问题简介

最长公共子串(Longest Common Substring)问题是计算机科学中的一个经典问题,是字符串处理中常见的一种问题。给定两个字符串,要求从中找出最长的公共子串,即在两个字符串中连续出现的最长的子串。

最长公共子串问题与最长公共子序列问题类似,但是要求找到的子串必须是连续的。例如,对于字符串"ABABC"和"BABCA",它们的最长公共子串为"ABC"。

2. 暴力解法

最简单的方法是使用暴力解法,遍历两个字符串的所有子串,然后逐个比较它们的每个字符,找出最长的公共子串。下面是PHP代码实现:

function findLongestCommonSubstring($str1, $str2) {

$maxLen = 0;

$maxSubstr = "";

// 遍历所有子串

for ($i = 0; $i < strlen($str1); $i++) {

for ($j = 0; $j < strlen($str2); $j++) {

$len = 0;

$substr = "";

// 比较每个字符

while ($i + $len < strlen($str1) && $j + $len < strlen($str2) && $str1[$i + $len] == $str2[$j + $len]) {

$substr .= $str1[$i + $len];

$len++;

}

// 更新最长公共子串

if ($len > $maxLen) {

$maxLen = $len;

$maxSubstr = $substr;

}

}

}

return $maxSubstr;

}

$str1 = "ABABC";

$str2 = "BABCA";

echo findLongestCommonSubstring($str1, $str2); // 输出 "ABC"

3. 动态规划解法

虽然暴力解法可以找到最长公共子串,但是时间复杂度较高,不适用于较大规模的字符串。动态规划是一种常用的解决最长公共子串问题的方法。

动态规划的思想是将一个大问题拆分成多个子问题,通过解决子问题来解决原来的问题。对于最长公共子串问题,可以使用一个二维数组来记录每个子问题的结果。下面是PHP代码实现:

function findLongestCommonSubstring($str1, $str2) {

$len1 = strlen($str1);

$len2 = strlen($str2);

$maxLen = 0;

$maxEndPos = 0;

// 创建二维数组,用于记录子问题的结果

$dp = array();

for ($i = 0; $i < $len1; $i++) {

$dp[$i] = array();

for ($j = 0; $j < $len2; $j++) {

$dp[$i][$j] = 0;

}

}

// 动态规划计算最长公共子串

for ($i = 0; $i < $len1; $i++) {

for ($j = 0; $j < $len2; $j++) {

if ($str1[$i] == $str2[$j]) {

if ($i == 0 || $j == 0) {

$dp[$i][$j] = 1;

} else {

$dp[$i][$j] = $dp[$i - 1][$j - 1] + 1;

}

// 更新最长公共子串的长度和结束位置

if ($dp[$i][$j] > $maxLen) {

$maxLen = $dp[$i][$j];

$maxEndPos = $i;

}

}

}

}

return substr($str1, $maxEndPos - $maxLen + 1, $maxLen);

}

$str1 = "ABABC";

$str2 = "BABCA";

echo findLongestCommonSubstring($str1, $str2); // 输出 "ABC"

4. 总结

最长公共子串问题是计算机科学中的一个重要问题,可以通过暴力解法和动态规划解法来求解。暴力解法简单直观,但是时间复杂度较高;动态规划解法通过拆分问题的思想,通过记录子问题的结果来求解最长公共子串,时间复杂度较低。

在实际应用中,可以根据具体情况选择合适的方法来解决最长公共子串问题。对于较小规模的字符串,暴力解法即可满足需求;而对于较大规模的字符串,动态规划解法更适合。

后端开发标签