给出一个整数数组,我该如何对它们进行排序:最大-最小-第二个最大-第二个最小?
我正在尝试: -按升序和降序复制和排序数组 -通过选择上述每个数组的开头来创建排序后的数组
我对Haskell编程不熟悉,但这是我所做的
sort :: [Int] -> [Int]
sort [] = []
sort (x:xs) = sort smaller ++ [x] ++ sort larger
where
smaller = filter (<= x) xs
larger = filter (> x) xs
wave :: [Int] -> [Int]
wave [] = []
wave [x] = [x]
wave (x:xs) = if length (x:xs)>1
then :
ascending = sort (x:xs)
descending = reverse (ascending)
iterator = length(x:xs)
if iterator > 0 && (length(ascending)==0 || length(descending)==0)
then do wave(x:xs) = head(descending) + head(ascending)
tail(descending)
tail(ascending)
在此先感谢您的帮助
答案 0 :(得分:5)
frontEndSort
使用列表xs
,它按降序对元素进行排序。接下来,将xs
中的每个元素与同一列表中的元素按升序配对。将每对转换为一个列表,然后展平整个列表。最后,我们采用与xs
中一样多的元素。
frontEndSort :: [Int] -> [Int]
frontEndSort xs = take (length xs) $ do
(x, y) <- zip <$> sortBy (comparing Down) <*> sort $ xs
[x, y]
答案 1 :(得分:2)
braid
函数逐个元素插入两个列表。接下来,我们将braid
应用于按升序和降序排列的列表。最后,由于最终重复了原始列表,因此我们只取原始列表的长度。
braid :: [Int] -> [Int] -> [Int]
braid [] as = as
braid ds [] = ds
braid (d:ds) (a:as) = d:a:braid ds as
wave :: [Int] -> [Int]
wave xs = take (length xs) braided
where asc = sort xs
desc = reverse asc
braided = braid desc asc
尽管我认为对于Haskell初学者来说,我的实现更容易理解,但我不得不说,在将我的解决方案与ƛƛƛ的解决方案进行对比之后,我的实现比他/她的慢了约4至7倍。
十万个长度列表:
一百万个长度列表:
reverse
用desc = reverse asc
替换desc = sortOn Down xs
会产生与s的应用解决方案和意愿理解列表实现相同的速度程序。
答案 2 :(得分:1)
另一种使用压缩的方式:
import Data.Ord
frontEndSort :: [Int] -> [Int]
frontEndSort xs =
zipWith (flip const) xs
( concat . getZipList . traverse ZipList
$ [sortBy (comparing Down) xs, sort xs] )
这里traverse ZipList :: [[b]] -> ZipList [b]
已将其生成为列表而不是元组。