代码之家  ›  专栏  ›  技术社区  ›  Frank Ponte

重复列表到元组的计数值,元组内的列表-Haskell

  •  2
  • Frank Ponte  · 技术社区  · 7 年前

    我在Haskell学习函数式编程,我做了这个练习 [a], z 具有 [a] 任何类型的列表和 z 我要在里面抹掉的元素 [答] 。这个问题很容易解决(即使是像我这样的Haskell新手),但我在打印输出的方式上遇到了问题。

    我需要创建一个 元组 其中第一个元素是没有 Z 元素及其找到的次数 Z 的内部 a .几个示例:

    • 输入: [2,3,4,2,2] 2
    • 输出: ([3,4],3)

    • 输入: [1,1,1,1] 1

    • 输出: ([],4)

    • 输入: [1,2,3,4] 5

    • 输出: ([1,2,3,4],0)

    到目前为止,我已经做了类似的事情,但我不知道如何继续:

    ex3 :: (Eq a, Num a) => [a] -> a -> ([a],Int)
    ex3 [] _ = ([],0)
    ex3 (x:xs) z | x == z = (xs,1) -- this line is wrong, but idk how to fix it
                 | otherwise = ([0],0) -- same here
    

    我分别解决了这两个问题(删除 Z 元素和计数次数 Z 在中 [答] 。如下所示:

    a) 正在删除 Z 要素:

    ex3a :: (Eq a) => [a] -> a -> [a]
    ex3a [] _ = []
    ex3a (x:xs) z | x == z = ex3a xs z
                  | otherwise = x : ex3a xs z
    

    b) 数了多少次 Z 在中 [答] :

    ex3b :: (Eq a) => [a] -> a -> Int
    ex3b [] _ = 0
    ex3b (x:xs) z | x == z = 1 + ex3b xs z
                  | otherwise = ex3b xs z
    
    3 回复  |  直到 7 年前
        1
  •  5
  •   melpomene    7 年前

    通常,这有助于你思考数学中的函数 归纳定义 。例如,函数的第一行可以如下所示:

    “” 这个 ex3 任何元素都是包含空列表和零的元组 “”

    ex3 [] _ = ([], 0)
    

    当然,对于非空列表,问题更难一些。就像在代码中一样,这里基本上有两种情况。

    “” 这个 ex3 非空列表和元素的 z 名单的头号人物是 等于 Z ex3 列表的 ,但前面有列表的标题“,所以我们可以这样写:

    ex3 [] _ = ([], 0)
    ex3 (x:xs) z | x /= z = (x:t, n)
                 | otherwise = ...
        where (t, n) = ex3 xs z
    

    所以这里我们递归调用 ex3 列表的尾部 xs ,得到结果元组 (t, n) 所以 t 包含“已擦除”的尾部,以及 n 删除元素的次数,以及 x /= z ,然后我们可以返回 (x:t, n) ,因为删除的数量没有变化,但我们必须提前 x 到列表中。

    “” 这个 ex3 非空列表和元素的 Z 其中列表的开头等于 Z ex3 列表的,但计数递增 “,因此:

    ex3 :: (Eq a, Num n) => [a] -> a -> ([a], n)
    ex3 [] _ = ([], 0)
    ex3 (x:xs) z | x /= z = (x:t, n)
                 | otherwise = (t, n+1)
        where (t, n) = ex3 xs z
    

    然后,我们获得了预期的结果:

    Prelude> ex3 [2,3,4,2,2] 2
    ([3,4],3)
    Prelude> ex3 [1,1,1,1] 1
    ([],4)
    Prelude> ex3 [1,2,3,4] 5
    ([1,2,3,4],0)
    
        2
  •  3
  •   Daniel Wagner    7 年前

    为了好玩,我将这样实现该功能:

    import Data.Foldable
    import Data.Monoid
    
    ex3 :: Eq a => [a] -> a -> ([a], Int)
    ex3 haystack needle = getSum <$> foldMap inject haystack where
        inject hay | hay == needle = ([], 1)
                   | otherwise     = ([hay], 0)
    

    我喜欢的是,递归模式是显而易见的——至少对那些熟悉Haskell标准库的人来说是如此——而无需仔细检查(因为它只是调用 foldMap )。

        3
  •  0
  •   user12457    7 年前

    分区函数使用谓词和列表;它生成一对列表,其中第一个元素满足谓词,第二个元素不满足谓词。

    import Data.List (partition)
    
    ex4 :: Eq a => [a] -> a -> ([a], Int)
    ex4 xs x = length <$> partition (/= x) xs