繁体   English   中英

不使用库函数对列表的一部分进行排序

[英]Sorting a part of a list without using library functions

我想对列表的前三个元素进行排序,而其他元素保持不变。 而且我不想使用任何库函数,因为我是Haskell的新手。

这是我到目前为止的内容:

{-# OPTIONS_GHC -Wincomplete-patterns #-}


sort2 (x, y) = if x > y then (y,x) else (x,y)
sort3 (x,y,z)
    | x > y && y > z = (z,y,x)
    | x > z && z > y = (y,z,x)
    | y > x && x > z = (z,x,y)
    | y > z && z > x = (x,z,y)
    | z > x && x > y = (y,x,z)
    | z > y && y > x = (x,y,z)
    | otherwise = (0,0,0)

--sortfirst3 :: [Int] -> [Int]
sortfirst3 (x:y:z:v:xs) =  sort3(x,y,z) : sortfirst3 (v:xs)

我正在尝试对前三个元素进行排序,将它们放在列表中,然后将其他元素放在另一个列表中,然后将它们彼此串联。 但是,由于类型差异元组和列表,这会产生错误。 我还有其他方法可以这样做吗?

您不需要涉及元组。 您可以将为元组编写的内容写为匹配的模式。

sortFirst3 [x, y] = if x > y then [y, x] else [x, y]
sortFirst3 [x, y, z]
    | x >= y && y >= z = [z, y, x]
    | x >= z && z >= y = [y, z, x]
    | y >= x && x >= z = [z, x, y]
    | y >= z && z >= x = [x, z, y]
    | z >= x && x >= y = [y, x, z]
    | z >= y && y >= x = [x, y, z]
sortFirst3 (x : y : z : ws) = sortFirst3 [x, y, z] ++ ws
sortFirst3 xs = xs

最后一行捕获未匹配的内容,即单例和空列表,它们在排序时保持不变。 由于元素可能重复出现,因此您在警卫中不应有严格的不平等。 还要注意,在您的代码中,即使您没有类型不匹配,对sortFirst3的递归调用也会是错误的,因为对前三个术语进行排序后,其余的前三个将被排序,依此类推。

sortfirst3 (x:y:z:v:xs) =  sort3(x,y,z) : sortfirst3 (v:xs)

此定义表示,将列表中的前4个元素从列表中删除,将前3个元素排序到一个元组中,然后将其与列表的其余部分一起包含在列表中第四个元素的(递归)结果上。

这揭示了要进行的三个更改。

首先,我们只需要匹配前3个元素,而不是前4个元素,但是我们也应该处理列表小于3个元素的情况。 我刚把它弄错了,但是你可以使用例如。 代替sort2

sortfirst3 (x:y:z:xs) =  sort3 (x,y,z) : sortfirst3 xs
sortfirst3 _ = error "Can't sort first 3 elements of list shorter than 3 elements"

其次,我们打算对前三个元素进行排序。 生成一个3元素列表。 (:) :: a -> [a] -> [a] 在第一个参数中接受一个元素(而不是列表),我们想要的是连接(++) :: [a] -> [a] -> [a]

sortfirst3 (x:y:z:xs) =  sort3 (x,y,z) ++ sortfirst3 xs

第三,我们打算不影响前三个元素,因此我们实际上不应该对列表的其余部分进行递归调用-否则,我们将列表按3个元素块排序。

sortfirst3 (x:y:z:xs) =  sort3 (x,y,z) ++ xs

现在,这几乎是正确的,但对于sort3 ,如您所识别的sort3 ,它会错误地返回一个元组而不是一个三元素列表。 kuoytfouy的答案对此有所帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM