首页 > 解决方案 > 连续列表元素的 Haskell 模式匹配

问题描述

我想检查列表中的下一个元素是否与前一个元素相同,并在 Haskell 中使用递归函数和模式匹配来增加计数,我该怎么做?我在想一些事情:

mrn [] = 0
mrn [x] = 1
mrn (x:xs) 
  |(x == mrn xs) = --what do I increment here? 
  otherwise --what here?

如果下一个元素不相同,我想重置计数并将前一个计数存储在其他地方

标签: haskellrecursionduplicatespattern-matchingcounting

解决方案


我们不会将数据存储在其他任何地方,而是存储在函数的输出中,或者在它的参数中,将它们从一个调用更新到另一个调用,因为 Haskell 中的数据是不可变的——如果x = 42,那么它42。它不能被更改。

0这意味着使用参数的初始值count。它必须由我们函数内部定义的内部“worker”函数使用,以免不相关的实现细节污染全局空间。

为了匹配两个连续的元素,我们使用(x:y:xs)模式:

countDups :: [a] -> Integer
countDups xs  =  go xs 0
   where
   go []  count = count
   go [x] count = count
   go (x:y:xs) count
      | your test = go (y:xs) (count+1)
      | otherwise = go (y:xs) count

您将需要进行必要的更正,以便它执行您想要的操作,并适当地更改警卫中的测试。

以上将计算列表中的所有重复项。如果您想要其他东西,即获取所有连续计数的列表,那么您需要让您的函数创建该列表

dupCounts :: [a] -> [Integer]
dupCounts xs  =  go xs 0 False
   where
   go []  count previousIsSame = [count]
   go [x] count previousIsSame = [count]
   go (x:y:xs) count previousIsSame 
      | your test = go (y:xs) (count+1) ....
      | otherwise = x : go (y:xs) 0 ....

希望完成/更改/代码应该很简单。


推荐阅读