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

Scala中创建元素1和2交替无连续重复的子列表

嘿,作为Scala新手碰到这种问题太正常啦!我猜你是想生成由1和2交替组成、完全没有连续重复数字的列表对吧?下面给你几种不同思路的实现代码,每一种都附带详细解释,帮你理解Scala的不同编程风格:

方法1:递归实现(函数式风格入门)

递归是Scala函数式编程的核心基础之一,这种方式逻辑直观,非常适合新手理解:

def alternateList(n: Int): List[Int] = n match {
  case 0 => Nil  // 长度为0时返回空列表
  case 1 => List(1)  // 长度为1时返回仅包含1的列表
  case _ =>
    val prevList = alternateList(n - 1)
    // 取上一个列表的最后一位,切换成另一个数字追加到末尾
    val nextNum = if (prevList.last == 1) 2 else 1
    prevList :+ nextNum
}

关键解释:

  • 用Scala的模式匹配处理不同长度的边界情况:
    • 当n=0直接返回空列表Nil;
    • 当n=1返回初始单元素列表(你也可以改成从2开始,只需要调整这个初始值);
    • 更长的列表则递归生成前n-1位的交替列表,再根据最后一位的值切换数字追加,保证绝对不会出现连续重复。

测试示例:

println(alternateList(5))  // 输出: List(1, 2, 1, 2, 1)
println(alternateList(6))  // 输出: List(1, 2, 1, 2, 1, 2)

方法2:用Stream生成无限交替序列(更灵活)

如果你需要一个可以按需截取的无限交替序列,Scala的Stream(懒加载序列)会是绝佳选择:

// 定义一个无限循环的交替流
val alternateStream: Stream[Int] = 1 #:: 2 #:: alternateStream
// 截取前n个元素转成列表
def alternateListFromStream(n: Int): List[Int] = alternateStream.take(n).toList

关键解释:

  • #::是Stream的懒加载构造符,只会在需要的时候生成下一个元素,不会一次性占用大量内存;
  • alternateStream通过自引用形成了1→2→1→2...的无限循环序列,用take(n)就能轻松获取指定长度的子列表。

测试示例:

println(alternateListFromStream(3))  // 输出: List(1, 2, 1)
println(alternateListFromStream(4))  // 输出: List(1, 2, 1, 2)

方法3:迭代式实现(命令式风格,适合Java转Scala的新手)

如果你更习惯传统命令式的写法,也可以用循环来实现:

def alternateListIterative(n: Int): List[Int] = {
  if (n <= 0) return Nil
  var currentNum = 1
  var result = List(currentNum)
  for (_ <- 2 to n) {
    currentNum = if (currentNum == 1) 2 else 1
    result = result :+ currentNum
  }
  result
}

关键解释:

  • 用var定义可变变量(Scala里更推荐用不可变变量,但这种写法更贴近你熟悉的命令式逻辑);
  • 从第二个元素开始循环,每次切换数字并追加到列表末尾,保证没有连续重复。

测试示例:

println(alternateListIterative(5))  // 输出: List(1, 2, 1, 2, 1)

额外小技巧:支持自定义起始数字

如果想让列表可以从1或2任意开始,只要给方法加个起始参数就行,比如修改递归方法:

def alternateListWithStart(n: Int, start: Int): List[Int] = n match {
  case 0 => Nil
  case 1 => List(start)
  case _ =>
    val prevList = alternateListWithStart(n - 1, start)
    val nextNum = if (prevList.last == 1) 2 else 1
    prevList :+ nextNum
}

测试从2开始的情况:

println(alternateListWithStart(4, 2))  // 输出: List(2, 1, 2, 1)

内容的提问来源于stack exchange,提问作者André Azevedo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 07:53:43