algorithm - 查找重复字符的函数式编程算法

标签 algorithm functional-programming repeat

我正在转换 "zxcvbn" password strength algorithm从 JavaScript 到 Scala。我正在寻找一种纯函数算法来查找字符串中重复字符的序列。

我知道我可以从 JavaScript 翻译命令式版本,但我希望尽可能避免产生副作用,因为函数式编程通常给出的所有原因。

算法可以是 Scala、Clojure、Haskell、F#,甚至是伪代码。

谢谢。

最佳答案

使用 Haskell 的标准高阶函数:

  • Data.List.group 查找列表中相等元素的运行:

    > group "abccccdefffg"
    ["a","b","cccc","d","e","fff","g"]
    
  • 我们关心这些运行的长度,而不是元素本身:

    > let ls = map length $ group "abccccdefffg"
    > ls
    [1,1,4,1,1,3,1]
    
  • 接下来,我们需要每个组的起始位置。这只是组长度的部分和,我们可以使用 scanl 计算:

    > scanl (+) 0 ls
    [0,1,2,6,7,8,11,12]
    
  • 压缩这两个列表可以得到所有对的起始位置和相应的长度:

    > zip (scanl (+) 0 ls) ls
    [(0,1),(1,1),(2,4),(6,1),(7,1),(8,3),(11,1)]
    
  • 最后,我们删除长度小于 3 的组。

    > filter ((>= 3) . snd) $ zip (scanl (+) 0 ls) ls
    [(2,4),(8,3)]
    

综合起来:

import Data.List (group)

findRuns :: Eq a => [a] -> [(Int, Int)]
findRuns xs = filter ((>= 3) . snd) $ zip (scanl (+) 0 ls) ls 
  where ls = map length $ group xs

关于algorithm - 查找重复字符的函数式编程算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13650326/

相关文章:

c++ - 如何在 C++ 中最好地实现 DPLL?

python - 减少Python字典中带有关键字参数的函数列表

r - 如何在 R 中模拟 Lisp 的 let 函数?

haskell - 如果我对返回值进行硬编码,为什么 Haskell 会给出类型错误?

Java 服务器猜谜游戏

java - 我应该如何找到重复的单词序列

生成二进制矩阵的算法

java - 减去 ASCII 值和简单地减去一个整数在算法效率方面有区别吗?

performance - 查找集合成员的有效方法

c++ - C++ 中的字符串乘法