如果两个单词很像,其实是他们有更长的公共子序列。求以下几组单词的最长公共子序列的长度
1.fish和fosh
2.recommend和reccommend
3.fish和vista
与最长公共子串很类似,但子序列遇到不同的字符时不能将相同字符组计数清零。需要连续计数,此时,需要将当前位置左侧或上侧的最大值填入到当前位置。
php:
// 找出两个单词的最长公共子序列
function findLongestSubSeq($word1, $word2)
{
$len1 = strlen($word1);
$len2 = strlen($word2);
$cell = array();
for ($i = 0; $i < $len1; $i++) {
for ($j = 0; $j < $len2; $j++) {
// 如果两个字符相同,则取其左上角的数值+1
if ($word1[$i] == $word2[$j]) {
if ($i > 0 && $j > 0) {
$cell[$i][$j] = $cell[$i - 1][$j - 1] + 1;
} else {
$cell[$i][$j] = 1;
}
} else {
if ($i > 0 || $j > 0) {
$v1 = 0;
if ($i > 0){
$v1 = $cell[$i - 1][$j];
}
$v2 = 0;
if ($j > 0){
$v2 = $cell[$i][$j - 1];
}
$cell[$i][$j] = max($v1, $v2);
}else{
$cell[$i][$j] = 0;
}
}
}
}
printCell($word1, $word2, $cell);
$maxLength = findMaxValue($cell);
echo $maxLength . "\n";
}
// 找出值最大的单元格
function findMaxValue($cell)
{
$max = 0;
foreach ($cell as $rows) {
foreach ($rows as $item) {
if ($item > $max) {
$max = $item;
}
}
}
return $max;
}
function printCell($word1, $word2, $cell)
{
$len1 = strlen($word1);
$len2 = strlen($word2);
echo " ";
for ($i = 0; $i < $len2; $i++) {
echo $word2[$i] . " ";
}
echo "\n";
for ($i = 0; $i < $len1; $i++) {
echo $word1[$i] . " ";
echo implode(‘ ‘, $cell[$i]) . "\n";
}
}
findLongestSubSeq("fish", "fosh");
findLongestSubSeq("recommend", "reccommend");
findLongestSubSeq("hish", "vista");
输出:
f o s h
f 1 1 1 1
i 1 1 1 1
s 1 1 2 2
h 1 1 2 3
3
r e c c o m m e n d
r 1 1 1 1 1 1 1 1 1 1
e 1 2 2 2 2 2 2 2 2 2
c 1 2 3 3 3 3 3 3 3 3
o 1 2 3 3 4 4 4 4 4 4
m 1 2 3 3 4 5 5 5 5 5
m 1 2 3 3 4 5 6 6 6 6
e 1 2 3 3 4 5 6 7 7 7
n 1 2 3 3 4 5 6 7 8 8
d 1 2 3 3 4 5 6 7 8 9
9
v i s t a
h 0 0 0 0 0
i 0 1 1 1 1
s 0 1 2 2 2
h 0 1 2 2 2
2
golang:
package main
import (
"fmt"
"math"
)
func main() {
findLongestSubSeq("fish", "fosh")
findLongestSubSeq("recommend", "reccommend")
findLongestSubSeq("fish", "vista")
}
func findLongestSubSeq(word1, word2 string) {
len1 := len(word1)
len2 := len(word2)
cell := make([][]int, len1)
for i := 0; i < len1; i++ {
cell[i] = make([]int, len2)
for j := 0; j < len2; j++ {
if word1[i] == word2[j] {
if i > 0 && j > 0 {
cell[i][j] = cell[i-1][j-1] + 1
}else{
cell[i][j] = 1
}
} else {
v1 := 0
if i > 0 {
v1 = cell[i-1][j]
}
v2 := 0
if j > 0 {
v2 = cell[i][j-1]
}
cell[i][j] = int(math.Max(float64(v1), float64(v2)))
}
}
}
val := findMaxValue(cell)
fmt.Println(val)
}
func findMaxValue(cell [][]int) int {
max := 0
for _, rows := range cell {
for _, item := range rows {
if item > max {
max = item
}
}
}
return max
}
输出:
3
9
2
原文:https://blog.51cto.com/ustb80/2434655