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

Scala字符串首字符模式匹配问题求助(Advent of Code练习)

解决Scala中字符串首字符模式匹配的递归问题

我明白你想用Scala实现类似Haskell的模式匹配来处理Advent of Code的问题,这个错误的核心是类型不匹配,咱们一步步解决它:

错误原因拆解

你看到的错误提示constructor cannot be instantiated to expected type; found : scala.collection.immutable.::[B] required: Array[Char],本质是:

  • ::是Scala中List特有的构造函数,用来匹配非空列表的头和尾(比如head :: tail)。
  • 你可能把字符串转成了Array[Char],或者直接用了String类型,这两种都不支持::模式匹配。
  • 另外,你写的"^"是字符串常量,但列表里的元素是Char类型,应该用单引号的'^'。

修正后的代码方案

首先,我们需要把输入字符串转换成List[Char](因为List天生支持模式匹配),然后调整匹配逻辑:

假设你的Coord类是类似这样的(包含方向移动方法):

case class Coord(x: Int, y: Int) {
  def up: Coord = copy(y = y + 1)
  def down: Coord = copy(y = y - 1)
  def left: Coord = copy(x = x - 1)
  def right: Coord = copy(x = x + 1)
}

然后修改递归函数:

def part1(visited: Set[Coord], current: Coord, directions: List[Char]): Set[Coord] = directions match {
  // 匹配非空列表的头是'^',递归处理剩余尾列表
  case '^' :: tail => part1(visited + current, current.up, tail)
  case 'v' :: tail => part1(visited + current, current.down, tail)
  case '<' :: tail => part1(visited + current, current.left, tail)
  case '>' :: tail => part1(visited + current, current.right, tail)
  // 空列表时,把当前位置加入已访问集合后返回
  case Nil => visited + current
}

调用方式

当你有输入字符串时,只需要把它转成List再传入:

val input = "^>v<" // 示例输入
val initialCoord = Coord(0, 0)
val result = part1(Set(initialCoord), initialCoord, input.toList)

优化建议(可选)

为了让函数调用更简洁,可以把递归逻辑封装成内部辅助函数,对外只暴露接收字符串的接口:

def part1(directions: String): Set[Coord] = {
  case class Coord(x: Int, y: Int) {
    def up: Coord = copy(y = y + 1)
    def down: Coord = copy(y = y - 1)
    def left: Coord = copy(x = x - 1)
    def right: Coord = copy(x = x + 1)
  }

  def helper(visited: Set[Coord], current: Coord, remaining: List[Char]): Set[Coord] = remaining match {
    case '^' :: tail => helper(visited + current, current.up, tail)
    case 'v' :: tail => helper(visited + current, current.down, tail)
    case '<' :: tail => helper(visited + current, current.left, tail)
    case '>' :: tail => helper(visited + current, current.right, tail)
    case Nil => visited + current
  }

  helper(Set(Coord(0, 0)), Coord(0, 0), directions.toList)
}

// 调用示例
println(part1("^>v<").size) // 输出 4

这样你只需要直接传入字符串,不用手动处理List转换和初始坐标,更符合Scala的简洁风格。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:52:17