如何用Scala函数式方法实现字符串相邻重复字符及计数统计
Scala 函数式实现相邻重复字符统计
需求说明
统计字符串中的相邻重复字符,输出字符及对应计数的拼接结果,示例:输入aaabbcda,输出为3a2b1c1d1a。
实现方案
方案1:foldLeft 实现(全版本兼容)
完全纯函数式实现,无任何可变变量,兼容所有Scala版本:
object StringTransformation extends App { val str = "aaabbcda" println(strTransform(str)) def strTransform(str: String): String = if (str.isEmpty) "" else str.tail.foldLeft(List((1, str.head))) { case (acc@(count, lastChar) :: rest, currChar) => if (currChar == lastChar) (count + 1, lastChar) :: rest else (1, currChar) :: acc }.reverse.map { case (cnt, c) => s"$cnt$c" }.mkString }
实现逻辑:
- 优先处理空字符串的边界情况
- 以
(计数1, 首字符)作为初始累计值,遍历字符串剩余所有字符 - 每次判断当前字符和累计器中最新的字符是否相同,相同则计数+1,不同则新增一条计数为1的记录
- 最后将累计结果反转,拼接为「计数+字符」格式的字符串即可得到最终结果
方案2:unfold 实现(Scala 2.13+ 支持)
逻辑更直观简洁,代码量更小:
def strTransform(str: String): String = Iterator.unfold(str) { remaining => Option.when(remaining.nonEmpty) { val (samePrefix, rest) = remaining.span(_ == remaining.head) (s"${samePrefix.length}${samePrefix.head}", rest) } }.mkString
实现逻辑:
- 通过
unfold迭代处理剩余字符串,每次拆分出开头所有连续相同的字符片段 - 生成对应片段的「计数+字符」串,剩余的字符串进入下一轮迭代,直到字符串为空
- 最后拼接所有迭代生成的片段即可得到结果
内容的提问来源于stack exchange,提问作者Abhinay
相关产品推荐
相关产品推荐

