对合并排序实现感到困惑

时间:2012-10-26 10:08:43

标签: scala

此行发生了什么,x正在与xs1连接,但xxs1未在任何地方定义?

case (x :: xs1, y :: ys1) =>

此外,下面有xy的价值是多少?合并是作为案例类的一部分递归调用的吗?

if( x < y) x :: merge(xs1 , ys)

以下是完整的Scala代码:

object mergesort {

    def msort(xs: List[Int]): List[Int] = {
        val n = xs.length / 2
        if(n == 0) xs
        else {
            def merge(xs: List[Int], ys: List[Int]): List[Int] = (xs , ys) match {
            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)
            }


        val (fst, snd) = xs splitAt n
        merge(msort(fst), msort(snd))
        }
    }                                         //> msort: (xs: List[Int])List[Int]

    val nums = List(2, -4, 5, 7, 1)           //> nums  : List[Int] = List(2, -4, 5, 7, 1)
    msort(nums)                               //> res0: List[Int] = List(-4, 1, 2, 5, 7)

}

4 个答案:

答案 0 :(得分:2)

case (x :: xs1, y :: ys1) =>  

::是模式匹配中的一种语法糖,可以将list解构为headtail

列表xs被解构为头x和尾xs

在模式匹配中::解构一个列表,与正常情况下的实际操作完全相反,construct列表。

阅读The Point of Pattern Matching in Scala

中的反构造对象

答案 1 :(得分:1)

(xs , ys) match {
     ...     
    case (x :: xs1, y :: ys1) 

模式匹配,它在声明序列匹配的同一语句中声明变量xxs1等。

上面的代码检查xs是否可以分解为头x和尾xs1的序列,如果是,则使头/尾可用于这两个变量中的连续代码块

回答你的第二个问题(因为没有其他人!),是的,merge函数(在外部函数中声明)是递归调用的。

答案 2 :(得分:0)

在scala中使用match-case关键字来执行模式匹配,这是一种使用几种机制(如case类和提取器)匹配/分解对象的方法。谷歌进行scala模式匹配,你会找到你需要的答案。

答案 3 :(得分:0)

以下是scala如何允许您在List上进行模式匹配的示例:

scala> List(1,2,3)
res0: List[Int] = List(1, 2, 3)

scala> res0 match {
     | case h :: t => "more than two elements, " + h + " is the first"
     | case _ => "less than two elements"
     | }
res1: java.lang.String = more than two elements, 1 is the first

请注意::左侧的case会分析其标题中的列表(1)及其尾部(列表的其余部分2, 3)和将值绑定到ht,这些值仅在第一个case内创建并限定范围。

以下是分解元组的方法:

scala> val tp = ("a", 1)
tp: (java.lang.String, Int) = (a,1)

scala> tp match {
     | case (a, b) => a + " is a string, " + b + " is a number"
     | case _ => "something missing"
     | }
res2: java.lang.String = a is a string, 1 is a number

在你问题的代码中,你将两个事物和模式匹配混合在列表元组(xs , ys)上。

case (x :: xs1, y :: ys1)正在分解其两个列表中的元组,并在各自的头部和尾部分解其两个列表。