为什么这个XQuery(Mergesort)代码片段无法正常工作?

时间:2013-03-30 16:21:27

标签: xml xpath merge xquery mergesort

在学习XQuery时,我正在尝试实现合并排序。

为了将两个已经排序的序列连接成一个,我想实现一个名为“merge”的辅助函数。

目前看起来像这样:

declare function local:merge($seq1 as xs:integer*, $seq2 as xs:integer*) as xs:integer*{

if(empty($seq1) and empty($seq2)) then ()
else if(empty($seq1)) then $seq2
else if(empty($seq2)) then $seq1
else

let $zahl1 := $seq1[1]
let $zahl2 := $seq2[2]

return 
if($zahl1 < $zahl2) then ($zahl1, local:merge(fn:subsequence($seq1,2), $seq2))
else if($zahl2 < $zahl1) then ($zahl2, local:merge($seq1, fn:subsequence($seq2,2)))
else ($zahl1, $zahl2, local:merge(fn:subsequence($seq1,2), fn:subsequence($seq2,2)))

};

我正在使用此调用测试我的代码:

local:merge((1,3,6,9,10), (1,2,4,6,8,11))

某种程度上结果并不总是正确的(在这下面是来自上面的调用的结果):

 1 2 3 4 6 6 8 9 10 8 11

这背后的想法是我总是检查序列的第一个数字是大于还是小于另一个序列中的序列。然后我会将较小的数字添加到我的结果中,将较小数字的序列切换为子序列而不添加刚刚添加的数字,然后再次递归。

中断条件是两个序列中的任何一个为空或两者都是。

我现在看不出我的错误,也许这是我忽略的一点点。

你能告诉我在哪里需要更改我的代码吗?

非常感谢你的帮助。

2 个答案:

答案 0 :(得分:1)

您在函数的第9行中有一个复制/粘贴错误,let $zahl2 := $seq2[2]应为let $zahl2 := $seq2[1]。您的其余功能正常工作。

但是你可以省略检查两个参数是否为空,因为下一个参数返回$seq2,它也是空的:

  if(empty($seq1)) then $seq2
  else if(empty($seq2)) then $seq1
  else
    let $zahl1 := $seq1[1]
    ...

答案 1 :(得分:0)

当然,更容易对其进行排序的方法是:

for $i in $sequence order by $i return $i