Haskell:列表的合并列表

Haskell:列表的合并列表,haskell,Haskell,给定一个列表对的列表::[a,a],我想返回可能的列表组合,其中子列表已合并到一个子列表的最后一个子列表匹配下一个子列表的头部 比如说 --如果前后两个列表匹配,则将其合并 merge :: Eq a => [[a]] -> [[a]] merge (x:y:ys) | last x == head y = merge $ (x ++ (drop 1 y)) : ys | otherwise = [] merge xs = xs co

给定一个列表对的列表
::[a,a]
,我想返回可能的列表组合,其中子列表已合并到一个子列表的最后一个子列表匹配下一个子列表的头部

比如说 --如果前后两个列表匹配,则将其合并

merge :: Eq a => [[a]] -> [[a]]
merge (x:y:ys) | last x == head y = merge $ (x ++ (drop 1 y)) : ys
               | otherwise    = []
merge xs       = xs

combinations :: Eq a => [[a]] -> [[a]]
combinations = nub . concatMap merge . permutations

λ= merge [1,2] [2,3]
[1,2,3]


-- there should be no duplicate results
λ= combinations [[1,3],[1,3],[1,3],[1,3],[2,1],[2,1],[2,1],[2,2],[3,2],[3,2],[3,2]]
[[1,3,2,2,1,3,2,1,3,2,1,3],[1,3,2,1,3,2,2,1,3,2,1,3],1,3,2,1,3,2,1,3,2,2,1,3]]

-- the result must be a completely merged list or an empty list
λ= combinations [[1,3], [3,1], [2,2]]
[]

λ= combinations [[1,3], [3, 1]]
[[1,3,1],[3,1,3]]

λ= combinations [[1,3],[3,1],[3,1]]
[[3,1,3,1]]

我无法完全理解高效执行此操作所需的递归。

我以此解决方案结束,但它包含重复项(您可以使用
Data.List(nub)
来消除它们)


我不确定我是否完全理解你想要做什么,所以这里只有一些注释和提示

给定一个列表对的列表
::[a,a]

(……)例如

λ=合并[1,2][2,3]

首先,这些不是成对的列表,列表中的每个元素都是一个整数而不是一对。它们恰好是包含两个元素的列表。因此,您可以说它们是
[Int]
类型或
[a]
类型的实例

子列表已在一个子列表的最后一个子列表上合并,该子列表与下一个子列表的头部匹配

这意味着列表的大小将增加,并且您将不断需要检查它们的第一个和最后一个元素。检查列表的最后一个元素意味着每次都要遍历它。你想避免这样

这表明列表的表示形式带有额外的信息,便于访问。你只需要最后一个元素,但我会把对称放在第一位和最后一位

-- lists together with their last element
data CL a = CL [a] a a 

cl :: [a] -> CL a 
cl [] = error "CL from empty list"
cl xs = CL xs (head xs) (last xs)

clSafe :: [a] -> Maybe (CL a)
clSafe [] = Nothing
clSafe xs = Just (cl xs)
 
clFirst (CL _ x _) = x
clLast  (CL _ _ x) = x

compatible cs ds = clLast cs == clFirst ds
也许更好,也许你应该

data CL a = CL [a] a a | Nil 
并包含一个与所有其他文件兼容的空列表


需要考虑的另一点是,例如,如果您有一个列表
xs
,并且希望查找列表
ys
,将其组合为
ys++xs
,那么您希望能够非常容易地访问带有给定最后一个元素的所有
ys
。这表明你应该把它们储存在一个合适的结构中。可能是一个哈希表。

似乎需要尝试列表中所有元素的排列。如果成对的列表说,
[[1,3],[3,1],[2,2]]
无法合并会发生什么?这类似于盒子堆叠问题,这不是一件简单的事情,因为当你开始像
[1,3]->[3,2]>..
[2,1]>[1,3]>..
这样链接时,会得到不同的结果。假设您希望结果中的子列表数量最少,则可以通过动态编程方法有效地解决该问题。我认为排列会产生浪费代码。你能更好地定义你的问题吗?。f、 e.根据您的示例,如果输入为
[[1,3],[3,1]]
,则输出应为
[[1,3,1]
,但根据您的描述,输出应为
[[1,3,1],[3,1,3]
。还有,如果有重复的,我们将由谁继续?例如,如果输入是
[[1,3],[3,1],[3,1]]
那么输出不应该是
[[1,3,1][1,3,1]
而不是
[[1,3,1]]
?@assembly.jc我最初的解决方案是使用
置换
,但这显然是低效的,甚至在这么小的范围内也是不切实际的case@LuisMorillo我添加了更多的示例和我的初始解决方案。重复项被删除,
[[1,3],[3,1],[3,1]]
应该会产生
[[3,1,3,1]]
,因为子列表可以进一步组合,所以您的解决方案似乎工作得很好。在我投票之前,我会试着理解它,等等。谢谢你能为你所做的添加一点描述吗?@matthias添加了一些评论。给定一个包含两个元素列表的列表,他们希望在匹配的边缘将它们链接起来,并返回所有可能的方法。e、 g.
linkUp[[1,2],[1,2]==>[]
。是的,他想把它们全部链接起来,这是我错过的一点
data CL a = CL [a] a a | Nil