【问题标题】:Quicksort in Q/KDB+Q/KDB+ 中的快速排序
【发布时间】:2015-02-21 01:26:56
【问题描述】:

我在一个网站上发现了这个快速排序实现:

q:{$[2>distinct x;x;raze q each x where each not scan x < rand x]};

我不明白这部分:

raze q each x where each not scan x < rand x

谁能一步一步给我解释一下?

【问题讨论】:

  • @Rahul 的回答很好地解释了它......但你只是出于好奇而试图理解它还是打算实际使用它?你绝对不应该使用它,它永远不会比内置的'asc'函数更快
  • 谢谢,只是了解,学习q

标签: kdb q-lang


【解决方案1】:

让我们一步一步来。我假设您对快速排序算法有基本的了解。此外,您提到的代码中有一处更正,我已在步骤 5 中更正。

示例列表:

                q)x: 1 0 5 4 3
  1. 从列表中获取一个随机元素,作为枢轴。

       q)  rand x
    

    假设它给了我们列表中的“4”。

  2. 将列表“x”拆分为 2 个列表。一个包含小于“4”的元素,另一个包含大于(或等于)“4”的元素。

    2.a) 首先将所有元素与枢轴进行比较(在我们的例子中为 4)

                  q)   (x<rand x)   /  11001b  : output is boolean list 
    

    2.b) 使用上面的布尔列表,我们可以从 'x' 中获取小于 '4' 的所有元素。方法如下:

         q) x where  11001b  / ( 1  0 3) : output
    

    所以我们需要其他表达式来获取大于(或等于)枢轴“4”的所有元素。有很多方法可以做到这一点 但是让我们看看代码中使用的那个:

          q)not scan (x<rand x)   / (11001b;00110b) : output
    

所以它给出了包含 2 个列表的列表。第一个是 (x

2.c) 所以现在我们可以使用 (2.b) 中的示例代码生成 2 个列表

       q) x where each (not scan (x<rand x)) / ((1 0 3);(5 4)): output list which has 2 lists
  1. 现在对每个列表应用相同的函数来对它们进行排序 即对列表的每个列表进行递归调用 ((1 0 3);(5 4))

        q) q each x where each (not scan (x<rand x))
    
    1. 在所有计算之后,应用“raze”来展平从每个递归调用返回的所有列表,以输出一个列表。

    2. 递归调用的结束条件是:当输入列表只有 1 个不同的元素时,直接返回它。

         q) 2>count distinct x
      

      注意:有一处更正。原始代码中缺少“计数”。

【讨论】:

  • Awesone,谢谢,虽然我熟悉 kdb 结构,但很难理解。
猜你喜欢
  • 2015-09-11
  • 2020-08-14
  • 1970-01-01
  • 2014-10-10
  • 2016-12-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多