此行发生了什么,x
正在与xs1
连接,但x
和xs1
未在任何地方定义?
case (x :: xs1, y :: ys1) =>
此外,下面有x
和y
的价值是多少?合并是作为案例类的一部分递归调用的吗?
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)
}
答案 0 :(得分:2)
在
case (x :: xs1, y :: ys1) =>
::
是模式匹配中的一种语法糖,可以将list
解构为head
和tail
列表xs
被解构为头x
和尾xs
。
在模式匹配中::
解构一个列表,与正常情况下的实际操作完全相反,construct
列表。
答案 1 :(得分:1)
此
(xs , ys) match {
...
case (x :: xs1, y :: ys1)
是模式匹配,它在声明序列匹配的同一语句中声明变量x
,xs1
等。
上面的代码检查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
)和将值绑定到h
和t
,这些值仅在第一个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)
正在分解其两个列表中的元组,并在各自的头部和尾部分解其两个列表。