想象一下,我有两个列表:
l1 = "Hey there"
l2 = "there is a turtle"
如何“连接”列表但删除与第一个列表末尾匹配的第二个列表的开头?
magic l1 l2 == "Hey there is a turtle"
更多例子,
magic "What's going on" "ing on in the world" == "What's going on in the world"
magic [1,2,3,2] [2,3,2,1] == [1,2,3,2,1]
magic [1..10] [5..20] == [1..20]
magic [1,2] [1,2] == []
我正在寻找的东西是连接列表然后删除部分 - 只在“联合” - 列表匹配的地方。
我看过的事情:
++
只是连接,所以不是我想要的。Data.List
的{{1}}列表差异运算符从第一个列表的前面开始,无论它在何处都从第二个列表中删除,所以不起作用。\\
,也许这是可行的,但我对haskell的理解还不够好。我也查看了the entire Data.List模块,找不到任何可以开箱即用的功能。
因此看起来有必要使我们自己的函数来执行此操作,在这种情况下,Prelude-function解决方案优于具有依赖关系的东西。
答案 0 :(得分:2)
这是一个简单的递归解决方案:
magic x y = f x y y
where f [] y z = y
f x [] z = x
f (x:xs) (y:ys) z = x : if x == y then f xs ys z else f xs z z
答案 1 :(得分:1)
我找到了办法:
import Data.List
overlap xs ys = xs ++ (ys \\ (head ((tails xs) `intersect` (inits ys))))
但我觉得它没有吸引力,我希望有人可以改进它。
答案 2 :(得分:0)
由于还没有人写这篇文章:
import Data.List (isPrefixOf)
magic xs ys = s' ++ r'
where
(s', r') = go xs
go [] = ([], [])
go (x:xs)
| isPrefixOf (x:xs) ys = ([], ys)
| otherwise = (x:s, r)
where
(s, r) = go xs