You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:Scala中按特定模式对字符串列表分组的实现方案

没问题,我来帮你搞定这个Scala分组需求!先把需求理清楚,然后一步步实现代码。

需求回顾

先明确输入输出和分组规则:

  • 输入列表:List("ac","bd","ce", "aaa","xyz","bbb","abc","kt","zb")
  • 期望输出:List(List("ac","bd","ce","zb"), List("aaa","bbb"), List("abc","xyz"), List("kt"))
  • 分组规则:
    1. 第一组:长度为2的字符串,第二个字符与第一个字符间隔1个字母(支持循环,比如zb,z之后隔一个是b)
    2. 第二组:长度为3,且三个字符完全相同(比如aaa)
    3. 第三组:长度为3,且三个字符是连续递增的字母(比如abc、xyz)
    4. 其他组:不符合上述任一规则的字符串,每个单独成一个列表

核心判断逻辑拆解

咱们把每个分组的判断逻辑转换成Scala可实现的条件:

  1. 第一组判断:
    字符串长度必须是2,计算两个字符的ASCII差值时要处理循环(加上26再取模26),如果结果等于2就符合条件。比如:
    • ac:c(99) - a(97) = 2 → 符合
    • zb:b(98) - z(122) = -24 → (-24 +26) %26 =2 → 符合
  2. 第二组判断:
    字符串长度为3,且所有字符都等于第一个字符,用s.forall(_ == s.head)就能轻松判断。
  3. 第三组判断:
    字符串长度为3,且第二个字符是第一个+1,第三个是第二个+1,即s(1) == s(0)+1 && s(2) == s(1)+1。

Scala实现代码

咱们通过打标签分组的方式实现:先给每个字符串分配组标签,按标签分组后再整理成期望格式。

object StringGrouping extends App {
  // 定义给字符串分配组标签的函数
  private def getGroupTag(s: String): Either[String, String] = {
    s match {
      // 处理第一组:长度2且间隔一个字母(含循环)
      case twoChar if twoChar.length == 2 =>
        val first = twoChar(0).toInt
        val second = twoChar(1).toInt
        if ((second - first + 26) % 26 == 2) Left("group1") else Right(s)
      // 处理第二组和第三组:长度3的情况
      case threeChar if threeChar.length == 3 =>
        if (threeChar.forall(_ == threeChar.head)) Left("group2")
        else if (threeChar(1) == threeChar(0) + 1 && threeChar(2) == threeChar(1) + 1) Left("group3")
        else Right(s)
      // 其他长度的字符串直接归为单独组
      case _ => Right(s)
    }
  }

  // 输入列表
  val input = List("ac","bd","ce", "aaa","xyz","bbb","abc","kt","zb")

  // 按标签分组
  val groupedByTag = input.groupBy(getGroupTag)

  // 提取三个核心分组
  val group1 = groupedByTag.getOrElse(Left("group1"), Nil)
  val group2 = groupedByTag.getOrElse(Left("group2"), Nil)
  val group3 = groupedByTag.getOrElse(Left("group3"), Nil)

  // 提取所有单独的分组(每个组只有一个元素)
  val individualGroups = groupedByTag.collect { case (Right(_), singleList) => singleList }

  // 合并所有分组得到最终结果
  val finalResult = List(group1, group2, group3) ++ individualGroups

  // 打印结果验证
  println(finalResult)
  // 输出:List(List(ac, bd, ce, zb), List(aaa, bbb), List(abc, xyz), List(kt))
}

代码说明

  • 用Either[String, String]作为标签:Left对应三个公共组的标识,Right对应单独组的字符串本身(确保每个单独字符串分到唯一的组)
  • groupBy会自动把相同标签的字符串归到同一个列表
  • 最后合并三个公共组和所有单独组,就得到了期望的输出格式
  • 这个逻辑还能处理边界情况,比如长度为1的字符串、不符合规则的3字符字符串(比如aab)等,都会被分到单独组里

内容的提问来源于stack exchange,提问作者fledgling

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 08:52:46