2017-01-14 1 views
2

Представьте меня есть два списка:Соединить (++) списки без перекрытия

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] == [] 

Что я ищу что-то, что будет объединять списки, а затем удалить части - только на «стыке» - где согласованного списки вверх.


Вещи я смотрел на:

  • ++ просто присоединяет, так это не то, что я после.
  • Список разностных операторов начинается с фронта первого списка и удаляет вхождение из второго списка независимо от того, где он находится, поэтому не будет работать.
  • Я не мог понять, могу ли я использовать stripPrefix для этого, может быть, это выполнимо, но мое понимание haskell недостаточно.

Я также просмотрел модуль the entire Data.List и не смог найти ничего, что делает то, что я хочу из коробки.

Таким образом, похоже, что для этого необходимо сделать свою собственную функцию, и в этом случае решение Prelude-функции предпочтительнее чем-то с зависимостями.

+2

Я не думаю, что есть стандартная функция библиотеки, которая поможет вам очень много с этим, но это действительно не так сложно, чтобы закодировать это самостоятельно, по крайней мере, если вы не возражаете против сложности _O_ (_n_ ²). – leftaroundabout

+0

@leftaroundabout Я не могу понять, как это сделать, я пытался какое-то время сейчас xD – theonlygusti

+1

Ну, наивный способ - попробовать все возможные префиксы (['tails'] (http: // hackage .haskell.org/package/base-4.9.1.0/docs/Data-List.html # v: хвосты) из первого списка), которые вы могли бы удалить из второго. Выберите самый длинный. – leftaroundabout

ответ

1

Я нашел способ сделать это:

import Data.List 
overlap xs ys = xs ++ (ys \\ (head ((tails xs) `intersect` (inits ys)))) 

, но я не нахожу его очень привлекательным, и я надеюсь кто-то может улучшить его.

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

 Смежные вопросы

  • Нет связанных вопросов^_^