【问题标题】:Sorting a part of a list without using library functions不使用库函数对列表的一部分进行排序
【发布时间】:2019-05-09 20:45:14
【问题描述】:

我想对列表的前三个元素进行排序,但保持其他元素不变。而且我不想使用任何库函数,因为我是 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)

我正在尝试对前三个元素进行排序,将它们放入一个列表中,然后将其他元素放入另一个列表中,然后将它们相互连接。但是,由于元组和列表的类型不同,这会产生错误。我还有其他方法吗?

【问题讨论】:

    标签: haskell


    【解决方案1】:

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

    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 的递归调用也是错误的,因为在对前三个术语进行排序后,将对其余的前三个进行排序,因此开。

    【讨论】:

      【解决方案2】:
      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 个元素进行排序,即。产生一个 3 元素列表。 (:) :: a -> [a] -> [a] 即。在第一个参数中接受一个元素(不是列表),我们想要的是串联(++) :: [a] -> [a] -> [a]

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

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

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

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

      【讨论】:

        猜你喜欢
        • 2016-06-01
        • 1970-01-01
        • 2011-01-17
        • 1970-01-01
        • 1970-01-01
        • 2011-01-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多