2

我需要编写一个代码,如果函数满足列表的大多数元素并且它不满足,则返回 True。例如:moreThan odd [1,2,3]True,但是moreThan odd [1,2,3,4]False。这是我的代码:

moreThan funkt xs
   = let
      control funkt n (x : xs)
         = control (if .?. then n + 1 else n) xs
      contol funkt _
         = False
   in
   control funtk 0 xs

有人可以说我如何控制它,我应该写什么.?. 谢谢!

4

5 回答 5

3

您编写的函数将为False所有参数返回,因为您总是False在列表结束时返回。

您编写的函数需要跟踪两个变量:处理的元素数和谓词为真的元素数。由于这段代码可能是家庭作业,我给你一个可以用来编写函数的构造。-- ???在这些地方填写您自己的代码。

moreThan :: (a -> Bool) -> [a] -> Bool
moreThan pred = go 0 0 where
  -- procd: number of elements processed
  -- holds: number of elements for which pred holds
  go procd holds (x:xs) = go procd' holds' xs where
     procd' = -- ???
     holds' = -- ???
  go procd holds []     = -- ???

如果您需要更多提示,请随时发表评论。


编写此函数的一种更惯用的方法是使用折叠:

moreThan pred = finalize . foldr go (0,0) where
  -- process one element of the input, produce another tuple
  go (procd,holds) x = -- ???
  -- produce a boolean value from the result-tuple
  finalize (procd,holds) = -- ???
于 2012-05-21T21:43:42.567 回答
2

了解您的图书馆!

import Data.List(partition)
import Data.Function(on)

moreThan f = (uncurry $ on (>) length) . partition f

如果不允许使用分区,自己写:

part f xs = (filter f xs, filter (not.f) xs)

或采用数字方式:

moreThan f xs = 2*s > length xs where s = sum $ map (fromEnum.f) xs
于 2012-05-22T06:27:14.230 回答
1

也许不是最有效的解决方案,但肯定是一个非常明确的解决方案,如下所示:

moreThan :: (a -> Bool) -> [a] -> Bool
moreThan f xs = length ts > length fs where
    ts = filter id bools
    fs = filter not bools
    bools = map f xs
于 2012-05-21T23:22:15.187 回答
1
majority :: (a -> Bool) -> [a] -> Bool
majority p = (0 <) . sum . map (\x -> if pred x then 1 else -1)

即在列表元素上映射(如果 pred x 则为 1,否则为 -1),然后对列表元素求和并查看结果是否 > 0。

于 2012-05-22T19:04:39.040 回答
0

我希望这是有效的(只遍历列表一次)但仍然相当清晰。

majority :: (a -> Bool) -> [a] -> Bool
majority pred = g . sum . map f
  where f x | pred x    = 1
            | otherwise = -1
        g y = 0 < y
于 2012-05-22T08:51:58.550 回答