连接(++)列表没有重叠

时间:2017-01-14 13:07:54

标签: list haskell concat

想象一下,我有两个列表:

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解决方案优于具有依赖关系的东西。

3 个答案:

答案 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