【问题标题】:What to set as default when the type is A (Scala)当类型为 A (Scala) 时默认设置什么
【发布时间】:2021-06-24 20:08:45
【问题描述】:

我在 Scala 中有一个练习,我必须将这种列表 (a,a,a,b,c,d,d,e,a,a) 转换为 ((a,3),(b,1),(c,1),(d,2),(e,1),(a,2))。 我显然知道我的算法还不正确,但我想从任何事情开始。 问题是我不知道如何打开该功能(最后一行),因为错误是无论我采用什么作为先前的参数,它都说需要:A,找到:Int/String 等。 前一个是作为前一个迭代的负责人。

def compress[A](l: List[A]): List[(A, Int)] = {
  def compressHelper(l: List[A], acc: List[(A, Int)], previous: A, counter: Int): List[(A, Int)] = {
    l match {
      case head::tail => {
        if (head == previous) {
          compressHelper(tail, acc :+ (head, counter+1), head, counter+1)
        }
        else {
          compressHelper(tail, acc :+ (head, counter), head, 1)
        }
      }
      case Nil => acc
    }
  }
  compressHelper(l, List(), , 1)
}

【问题讨论】:

  • 你不能使用Option[A]来代替,特别是因为你不会总是有前一个元素。

标签: scala design-patterns pattern-matching matching tail-recursion


【解决方案1】:

您不需要显式传递previous,只需查看累加器即可:

def compress[A](l: List[A], acc: List[(A, Int)]=Nil): List[(A, Int)] =
   (l, acc) match {
       case (Nil, _) => acc.reverse
       case (head :: tail, (a, n) :: rest) if a == head =>
            compress(tail, (a, n+1) :: rest)
       case (head :: tail, _) => compress (tail, (head, 1) :: acc)
}

【讨论】:

  • 类型不匹配。必需:List[(A, Int)], found: Iterable[(A, Int)] 我在编译时遇到这种错误。就是关于这个 acc.reversed
  • 好吧,我的错,这只是关于 acc.reverse,而不是反转 :) 谢谢。我有一个问题 - 你使用 (a, n) :: rest,因为列表就像 List((a,b))。因此,例如,如果我有一个类似于 List((a,b,c,d), (e,f,g,h)) 的列表,我将不得不写 (a,b,c,d)::休息而不是头::尾?所以使用 head :: tail 仅用于情况,当列表中有单个元素时?
  • @squall head::tail 将列表解构为第一个元素和其余元素。如果 list 包含元组,则 head 的值最终将成为一个元组(如 (a,b,c,d) 或其他)。如果你不关心元组的单个元素,你仍然可以做head::tail,只想要整个事情。或者你可以像(a, _, c, _) :: tail 那样进一步解构它。您可以根据需要尽可能多地嵌套这些 un​​applies ...case (Some((a,b,c))::_, (x :: y :: z :: _), _)::tail => ...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多