【问题标题】:Haskell Pattern Matching for consecutive list elements连续列表元素的 Haskell 模式匹配
【发布时间】:2021-11-18 21:39:11
【问题描述】:
我想检查列表中的下一个元素是否与前一个元素相同,并使用 Haskell 中的递归函数和模式匹配来增加计数,我该怎么做?
我在想一些类似的事情:
mrn [] = 0
mrn [x] = 1
mrn (x:xs)
|(x == mrn xs) = --what do I increment here?
otherwise --what here?
如果下一个元素不相同,我想重置计数并将前一个计数存储在其他地方
【问题讨论】:
标签:
haskell
recursion
duplicates
pattern-matching
counting
【解决方案1】:
我们不会将我们的数据存储在函数的输出中,或者它的参数中,将它们从一个调用更新到另一个调用,因为 Haskell 中的数据是不可变的——如果x = 42,那么它是 42. 无法更改。
这意味着对count 参数使用初始值0。它必须由我们函数内部定义的内部“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 ....
完成/更改/代码应该很简单,希望如此。