求助: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")) - 分组规则:
- 第一组:长度为2的字符串,第二个字符与第一个字符间隔1个字母(支持循环,比如
zb,z之后隔一个是b) - 第二组:长度为3,且三个字符完全相同(比如
aaa) - 第三组:长度为3,且三个字符是连续递增的字母(比如
abc、xyz) - 其他组:不符合上述任一规则的字符串,每个单独成一个列表
- 第一组:长度为2的字符串,第二个字符与第一个字符间隔1个字母(支持循环,比如
核心判断逻辑拆解
咱们把每个分组的判断逻辑转换成Scala可实现的条件:
- 第一组判断:
字符串长度必须是2,计算两个字符的ASCII差值时要处理循环(加上26再取模26),如果结果等于2就符合条件。比如:ac:c(99) - a(97) = 2 → 符合zb:b(98) - z(122) = -24 → (-24 +26) %26 =2 → 符合
- 第二组判断:
字符串长度为3,且所有字符都等于第一个字符,用s.forall(_ == s.head)就能轻松判断。 - 第三组判断:
字符串长度为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
相关产品推荐
相关产品推荐

