【发布时间】:2018-11-01 19:19:00
【问题描述】:
我正在编写一个函数来按元组或三元组对给定列表进行排序。它应该按列表的两个元素之间的数字对其进行排序。
例如,如果给定列表是[1,2,3,6,7],它应该返回[[1,2,3], [6,7]]
因为 1,2 和 2,3 之间以及 6,7
这是我的代码:
import Data.List
check :: [Int] -> [[Int]]
check listCopy@(x:xs) =
let sorted = sort (listCopy)
in if (length sorted > 1)
then if ((sorted !! 1 ) - (sorted !! 0)) == 1 || ((sorted !! 1 ) - (sorted !! 0)) == 0
then [[x] ++ check(xs) !! 0]
else [[x]] ++ check(xs)
else [[x]]
check [] = [[]]
if ((sorted !! 1 ) - (sorted !! 0)) == 1 || ((sorted !! 1 ) - (sorted !! 0)) == 0 正在检查列表的两个元素之间是否有 0 个数字
如果上述语句为 True,则 [[x] ++ check(xs) !! 0] 将把该元素添加到列表中并再次调用该函数并获取它返回的第一个元素。示例:[1,2,3,6,7] -> [[1 ++ check [2,3,6,7]]] -> [[1,2 ++ check[3,6,7]]] 等等...
但是,当if ((sorted !! 1 ) - (sorted !! 0)) == 1 || ((sorted !! 1 ) - (sorted !! 0)) == 0 为 False 时,它应该 else [[x]] ++ check(xs) 将元素设置在列表中的列表中并再次调用函数并在列表中创建另一个新列表。示例:[[1,2 ++ check[3,6,7]]] -> 是 6-3 == 0 或 1(False) 返回 [[1,2,3]] + check[6,7] 这应该会导致 [[1,2,3], [6,7]]
调用check[1,2,3,6,7] 但返回[[1,2,3]]。我没有错误,
但据我所知[[1,2]] ++ [[3,4]] 应该导致[[1,2], [3,4]] 这正是我在else [[x]] ++ check(xs) 中所做的事情,不知何故我的功能就在那里结束了。我在哪里犯了错误,或者它做了我错过的事情?
【问题讨论】:
-
您的代码绝不会计算
[[1,2]] ++ [[3,4]]。您的输入列表中甚至没有4。 -
尽量远离
!!。需要考虑三类列表:空列表[]、单例列表x:[](又名[x])和一般情况(x:y:ys)。另外,用check' :: [Int] -> [[Int]]解决排序列表的主要问题;然后check = check' . sort。无需在每次递归调用中对列表进行(重新)排序。 -
提示:递归分组
(y:ys)后,x要么自己进入一个组,要么被添加到包含y的组的开头。 -
不要使用
length, !!, head, tail,除非你真的必须——通常你不需要。而不是检查if length sorted > 1 then ...使用case sorted of (x1:x2:rest) -> ... ; _ -> ...,这样您就可以在没有!!的情况下访问第一个和第二个元素。
标签: haskell