Megre两个排序的数组,列表与数组

时间:2017-09-10 17:44:43

标签: arrays scala list

此函数合并两个排序列表。它需要两个列表作为参数并返回一个。

def merge(xs : List[Int], ys : List[Int]) : List[Int] = {
  (xs, ys) match {
    case (Nil, Nil) => Nil
    case (Nil, ys) => ys
    case (xs, Nil) => xs
    case (x :: xs1, y :: ys1) =>
      if(x < y) x :: merge(xs1, ys)
      else y :: merge(xs, ys1)
  }
}

我想通过将参数类型从List更改为Array来重写此函数,但它不起作用。然而,从List到Seq它起作用了。你能告诉我什么不适用于阵列吗?

def mergeDontWork(xs : Array[Int], ys : Array[Int]) : Array[Int] = {
  (xs, ys) match {
    case (Array.empty,Array.empty) => Array.empty
    case (Array.empty, ys) => ys
    case (xs, Array.empty) => xs
    case (x +: xs1, y +: ys1) => if(x < y) x +: merge2(xs1, ys)
      else y +: merge2(xs, ys1)
  }
}

错误来自代码部分:if(x < y) x +: merge2(xs1, ys):数组[Any]不符合预期类型Array [Int]

修改

由于pedromss和Harald提出的解决方案,我终于明白了如何从List到Array。我通过使尾部递归来修改函数。

    def mergeTailRecursion(xs : Array[Int], ys : Array[Int]) : Array[Int] ={

       def recurse( acc:Array[Int],xs:Array[Int],ys:Array[Int]):Array[Int]={

            (xs, ys) match {

                 case (Array(),Array()) => acc
                 case (Array(), ys) => acc++ys
                 case (xs, Array()) => acc++xs
                 case (a@Array(x, _*), b@Array(y, _*)) =>
                     if (x < y) recurse(acc:+x, a.tail, b)
                           else     recurse( acc:+y, a, b.tail)

           }

        }

           recurse(Array(),xs,ys)
     }

2 个答案:

答案 0 :(得分:1)

最后一个模式匹配案例中unapply的{​​{1}}方法似乎无法解析为正确的+:Int类型。

您可以尝试这样的事情:

Array[Int]

不幸的是,构造case (Array(x, xs1 @_*), Array(y, ys1 @_*)) => if (x<y) x +: mergeDontWork(xs.tail, ys) else y +: mergeDontWork(xs, ys.tail) 导致xs1属于xs1 @_*类型,因此也无法将其传递给递归调用。我使用Seq[Int]作为解决方法。

答案 1 :(得分:1)

  • 您无法在Array.empty上进行模式匹配,因为它是一种方法。请改用Array()
  • (x +: xs1, y +: ys1)似乎不是有效的匹配表达式。更改为(x +: xs1, y +: ys1)

编译代码版本:

object Arrays extends App {

  def merge(xs: Array[Int], ys: Array[Int]): Array[Int] = {
    (xs, ys) match {
      case (Array(), Array()) => Array.empty
      case (Array(), ys2)         => ys2
      case (xs2, Array())         => xs2
      case (xs1@Array(x, _*), ys1@Array(y, _*)) =>
        if (x < y) x +: merge(xs1.tail, ys)
        else y +: merge(xs, ys1.tail)
    }
  }

  merge(Array(1, 2, 3), Array(4, 5, 6)).foreach(println)

}

有关方法的模式匹配的说明,请参阅[here | Why can't I pattern match on Stream.empty in Scala?

和[here | How do I pattern match arrays in Scala?有关_*的说明。基本上它会匹配任意数量的参数。

来自[documentation | https://www.scala-lang.org/files/archive/spec/2.11/08-pattern-matching.html]

的关于xs1@的Lastlty
  

图案装订器

     

Pattern2 :: = varid` @&#39; Pattern3

     

模式绑定器xx @ pp由模式变量xx和模式pp组成。变量xx的类型是模式pp的静态类型TT。此模式匹配模式pp匹配的任何值vv,前提是运行时类型的vv也是TT的一个实例,它将变量名称绑定到该值。

你也可以用

来做
case (Array(x, _*), Array(y, _*)) =>
            if (x < y) x +: merge(xs.tail, ys)
            else y +: merge(xs, ys.tail)