haskell 验证列表中是否有三个相同的元素和两个相同的元素

wyyhbhjk  于 2023-08-06  发布在  其他
关注(0)|答案(2)|浏览(138)

我从列表[1..6]中得到一个5个元素的列表,按升序排序,我必须开发两个函数:

  • 检查是否存在 * 恰好 * 4个相等的元素(例如,111124444515555),
  • 检查是否存在 * 恰好 * 3个相等元素,以及 * 恰好 * 2个相等元素(例如,2224411122

我可以假设像numberOfOccurrencesisPermutationisSortedmaximumminimum这样的函数。

numberOfOccurrences :: Eq a => a -> [a] -> Int
numberOfOccurrences _ [] = 0
numberOfOccurrences x (y:ys)
  | x == y    = 1 + numberOfOccurrences x ys
  | otherwise = numberOfOccurrences x ys

isPermutation :: Eq a => [a] -> [a] -> Bool
isPermutation [] [] = True
isPermutation xs [] = False
isPermutation xs (y:ys) | length xs /= length (y:ys) = False
                        | otherwise = isPermutation (delete y xs) ys

字符串
我对第二个问题的解决方案是:

p :: [Int] -> Bool
p xs = 3 == maximum (map length (group xs))


但是,我应该使用函数isPermutationnumberOfOccurrences。关于这个问题有什么提示吗?
感谢丹尼尔瓦格纳发现我的错误。我想这是2的解。

p :: [Int] -> Bool
p xs = 3 == maximum ns && length ns == 2
    where 
        ns = (map length (group xs))


然而,这不是所需的解决方案。

hk8txs48

hk8txs481#

就我个人而言,我会从超级愚蠢的事情开始。

fourEqual [a, b, c, d, e] =
       (a == b && b == c && c == d && d /= e)
    || (a /= b && b == c && c == d && d == e)

字符串
它很容易写,很容易读,而且效率也不是特别低。
类似的策略适用于另一个。

6qqygrtg

6qqygrtg2#

虽然这不使用命名的函数,但我会开发一个行程编码,这很容易,因为我们知道元素是排序的。

rle :: Eq a => [a] -> [(a, Int)]
rle [] = []
rle lst = reverse $ go lst []
  where
    go [] acc = acc
    go (x:xs) [] = go xs [(x, 1)]
    go (x:xs) ((y, c):ys) 
      | x == y = go xs ((y, c+1):ys)
      | otherwise = go xs ((x, 1):(y, c):ys)

字符串
现在我们只需要能够计算第二个元素为3或4的元组的数量。

ghci> length $ filter (\(_, c) -> c == 4) $ rle [1,1,1,2,4,5]
0
ghci> length $ filter (\(_, c) -> c == 4) $ rle [1,1,1,1,2,4,5]
1
ghci> length $ filter (\(_, c) -> c == 4) $ rle [1,1,1,1,2,4,4,4,4,5]
2

相关问题