如何删除haskell列表中的第二大元素?

如何删除haskell列表中的第二大元素?,haskell,Haskell,我创建了一个程序来删除第一个最小的元素,但我不知道如何删除第二个最大的元素: 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 < bi

我创建了一个程序来删除第一个最小的元素,但我不知道如何删除第二个最大的元素:

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
无最大值(x:xs)=
withoutBiggestImpl(最大x x x)[](x:x)
哪里
最大::(Ord a)=>a->[a]->a
最大的,最大的
最大的(x:xs)=
如果xa->[a]->[a]->[a]->[a]
WithoutBiggestSimplBigBefore(x:xs)=
如果big==x,那么
在++xs之前
其他的
Without biggestimpl big(在+++[x]之前)xs

这是一种可能性,当然不是最好的

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!!我|我有可能,当然不是最好的

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不清楚OP是在寻找最大的(正如名称
中没有最大的
所暗示的)还是什么。在这种情况下,一个解决方案是将
过滤器::(a->Bool)->[a]->[a]
前奏曲中的
最大值::Ord a=>[a]->a
函数组合起来

withoutBiggest l = filter (/= maximum l) l

不清楚OP是在寻找最大的(正如没有最大的
的名称所暗示的)还是什么。在这种情况下,一种解决方案是将
过滤器::(a->Bool)->[a]->[a]->[a]
最大值::Ord a=>[a]->a
函数从
前奏曲中组合起来

withoutBiggest l = filter (/= maximum l) l

这里有一个简单的解决方案

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>

这里有一个简单的解决方案

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>

以下是从列表中删除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..]

以下是从列表中删除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..]

通过先查找最大的元素,然后对其进行过滤,可以删除最大的元素:

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
作出的假设:

  • 您希望删除第二大元素的每个匹配项
  • 当列表中有0/1个元素时,就没有第二个元素,因此也就没有第二大元素。如果列表中没有不存在的元素,则等同于拥有列表
  • 当列表仅包含与最大xs值相等的值时,即使总共可能有两个或多个元素,也没有第二大元素
  • Ord
    type类实例意味着一个总排序。否则,您可能会有多个不相等的最大值;否则,选择最大值和第二大值是没有明确定义的

您可以先找到最大的元素,然后对其进行过滤,从而删除最大的元素:

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
作出的假设:

  • 您希望删除第二大元素的每个匹配项
  • 当列表中有0/1个元素时,就没有第二个元素,因此也就没有第二大元素。如果列表中没有不存在的元素,则等同于拥有列表
  • 当列表仅包含与最大xs值相等的值时,即使总共可能有两个或多个元素,也没有第二大元素
  • Ord
    type类实例意味着一个总排序。否则,您可能会有多个不相等的最大值;否则,选择最大值和第二大值是没有明确定义的


这是一个有序列表吗?对列表进行排序,找到第二大元素,然后从原始列表中删除该元素。需要考虑很多边缘情况:如果列表为空怎么办?如果它只有一个元素怎么办?如果它包含第二大元素的重复条目怎么办?如果所有元素都相同怎么办?同意@MarkSeemann,m任何悬而未决的问题。这是一个有序的列表吗?对列表进行排序,找到第二大元素,然后从原始列表中删除该元素。需要考虑很多边缘情况:如果列表为空怎么办?如果它只有一个元素怎么办?如果它包含第二大元素的重复条目怎么办?如果所有元素都相同怎么办?同意对于@MarkSeemann,有很多悬而未决的问题。这个解决方案的一个可能问题是,如果列表是常数,我们会得到空列表。但是OP没有给出这种特殊情况下的精确性,所以我们无法真正回答…这是问题定义的结果。如果最大元素的所有副本都必须删除,在这种情况下,空列表是正确的输出。对我来说,这似乎不是一个“问题”。这是一种看待问题的方式,但是OP呢?也许他有另一个想法,我们不知道。这不是对你答案的批评。我只是说我们遗漏了一些“参数”提供适当的答案。此解决方案的一个可能问题是,如果列表为常量,我们将得到空列表。但OP没有给出此类特定情况的精确性,因此我们无法真正回答…这是问题定义的结果。如果必须删除最大元素的所有重复项,则在这种情况下,空列表是正确的输出。对我来说,这似乎不是一个“问题”。这是一种看待问题的方式,但是OP呢?也许他有另一个想法,我们不知道。这不是对你答案的批评。我只是说我们遗漏了一些“参数”提供适当的答案。
deleteN
是否等于
take
?否,
deleteN
删除第n个位置的项目。
take
取第一个n元素不是
deleteN
等于
take
?否,
deleteN
删除第n个位置的项目。
take
取第一个n元素 elements@MERCURYEDITS这是因为
secondmagnet
@MERCURYEDITS中的列表是空的,这是因为