最大公共子串的长度
【题目】已知两个串s1 和s2,求它们共同的子串中,最大长度是多少。
求的只是最大长度,并不要求找出是哪个子串(或哪些子串),应该比较容易一些。
简单递归处理应该行得通,但效率就没准儿了。
maxSub :: String -> String -> Int
maxSub [] _ = 0
maxSub _ [] = 0
maxSub xx@(x:xs) yy@(y:ys)
| x /= y = max f1 f2
| otherwise = maximum [f xs ys + 1, f1, f2]
where
f1 = maxSub xs yy
f2 = maxSub xx ys
f [] _ = 0
f _ [] = 0
f (p:ps) (q:qs) | p /= q = 0
| otherwise = f ps qs + 1
main :: IO ()
main = do
print $ maxSub "abcd" "ddbcdabd"
print $ maxSub "abcdefafabcd" "xbcdefabcxdddd"
果不其然,运行太慢啊。
还不如直接笛卡尔积了,来一个。
import Data.List (tails, maximum)
maxSub :: String -> String -> Int
maxSub xs ys = maximum [f x y 0 | x <- tails xs, y <- tails ys]
where f [] _ n = n
f _ [] n = n
f (x:xs) (y:ys) n
| x /= y = n
| otherwise = f xs ys (n+1)
main :: IO ()
main = do
print $ maxSub "aaaabbbbbcccccccccdddddddd" "bbbaaaccccccccddddddddddaaa"
print $ maxSub "abcdefafabcd" "xbcdefabcxdddd"
注意, 是 tails 不是 tail
实际上是把公共子串问题,转化为最大公共前缀问题了。