我创建了一个删除第一个最小元素的程序,但我不知道如何做第二大元素:
withoutBiggest (x:xs) =
withoutBiggestImpl (biggest x xs) [] (x:xs)
where
biggest :: (Ord a) => a -> [a] -> a
biggest big [] = big
biggest big (x:xs) =
if x < big then
biggest x xs
else
biggest big xs
withoutBiggestImpl :: (Eq a) => a -> [a] -> [a] -> [a]
withoutBiggestImpl big before (x:xs) =
if big == x then
before ++ xs
else
withoutBiggestImpl big (before ++ [x]) xs
答案 0 :(得分:1)
可能性,肯定不是最好的。
import Data.Permute (rank)
x = [4,2,3]
ranks = rank (length x) x -- this gives [2,0,1]; that means 3 (index 1) is the second smallest
然后:
[x !! i | i <- [0 .. length x -1], i /= 1]
嗯..不是很酷,让我花点时间思考更好的事情,我会编辑我的帖子。
此外我以前的解决方案是错误的。这个应该是正确的,但同样不是最好的:
import Data.Permute (rank, elems, inverse)
ranks = elems $ rank (length x) x
iranks = elems $ inverse $ rank (length x) x
>>> [x !! (iranks !! i) | i <- filter (/=1) ranks]
[4,2]
一个优点是,我认为这保留了列表的顺序。
答案 1 :(得分:1)
这是一个简单的解决方案。
Prelude> let list = [10,20,100,50,40,80]
Prelude> let secondLargest = maximum $ filter (/= (maximum list)) list
Prelude> let result = filter (/= secondLargest) list
Prelude> result
[10,20,100,50,40]
Prelude>
答案 2 :(得分:1)
这是一个从列表中删除n个最小元素的解决方案:
import Data.List
deleteN :: Int -> [a] -> [a]
deleteN _ [] = []
deleteN i (a:as)
| i == 0 = as
| otherwise = a : deleteN (i-1) as
ntails :: Int -> [a] -> [(a, Int)] -> [a]
ntails 0 l _ = l
ntails n l s = ntails (n-1) (deleteN (snd $ head s) l) (tail s)
removeNSmallest :: Ord a => Int -> [a] -> [a]
removeNSmallest n l = ntails n l $ sort $ zip l [0..]
编辑:
如果您只想删除第二个最小元素:
deleteN :: Int -> [a] -> [a]
deleteN _ [] = []
deleteN i (a:as)
| i == 0 = as
| otherwise = a : deleteN (i-1) as
remove2 :: [a] -> [(a, Int)] -> [a]
remove2 [] _ = []
remove2 [a] _ = []
remove2 l s = deleteN (snd $ head $ tail s) l
remove2Smallest :: Ord a => [a] -> [a]
remove2Smallest l = remove2 l $ sort $ zip l [0..]
答案 3 :(得分:0)
目前尚不清楚OP是否正在寻找最大的(如名称withoutBiggest
所暗示的)或什么。在这种情况下,一种解决方案是合并filter :: (a->Bool) -> [a] -> [a]
中的maximum :: Ord a => [a] -> a
和Prelude
函数。
withoutBiggest l = filter (/= maximum l) l
答案 4 :(得分:0)
您可以先删除最大的元素,然后对其进行过滤:
withoutBiggest :: Ord a => [a] -> [a]
withoutBiggest [] = []
withoutBiggest xs = filter (/= maximum xs) xs
然后你可以用同样的方式删除第二大元素:
withoutSecondBiggest :: Ord a => [a] -> [a]
withoutSecondBiggest xs =
case withoutBiggest xs of
[] -> xs
rest -> filter (/= maximum rest) xs
做出的假设:
maximum xs
的值时,即使可能总共有两个或更多元素,也没有第二大元素。Ord
类型类实例意味着总排序。否则,您可能有多个不相等的最大值;否则哪一个被选为最大的,而第二大的则没有明确定义。