我正在学习Dyalog APL。我实现了一个二进制堆,它似乎可以工作。我如何使它看起来更像APL (而不是Python)?
⎕io←0
heappush←{(⍺,⍵)siftdown 0(≢⍺)}
heappop←{
heap←⍵
last←⊃¯1↑heap ⋄ rest←¯1↓heap
0=≢rest:rest last
r←heap[0]
(((last@0)rest)siftup 0)r
}
siftdown←{
heap←⍺
start pos←⍵
item←pos⌷heap
newpos←{
⍵≤start:⍵
parentpos←⌊(⍵-1)÷2
parent←parentpos⌷heap
item发布于 2020-04-06 05:02:52
我如何使它看起来更像APL (而不是Python)?
假设你的意思是“以一种功能更强、命令更少的方式”,
O(\log n)操作(堆合并)。您也可以查看插图不错。算法中的改进
⎕IO←1代替。默认情况下,基于数组的堆使用基于0的索引,因此父-子关系稍微有些尴尬:
\begin{align} \text{left child}&=1+2\times\text{parent} \\ \text{right child}&=2+2\times\text{parent} \\ \text{parent}&=\Bigl\lfloor \frac{\text{child} - 1}2 \Bigr\rfloor \end{align}
如果您使用基于1的索引,它会变得稍微干净一些:
\begin{align} \text{left child}&=2\times\text{parent} \\ \text{right child}&=1+2\times\text{parent} \\ \text{parent}&=\Bigl\lfloor \frac{\text{child}}2 \Bigr\rfloor \end{align}
我没有其他更好的想法来利用APL的优势,因为底层的算法纯粹是命令式的。
的一般技巧
~heap[chp]),请使用单个等效函数(例如,heap[chp]≥heap[rpos])。当你连接两个标量时,更喜欢串联(例如0,≢⍺)而不是搁浅(例如0(≢⍺))。在实现算法时,不要修改现有变量的内容(例如,避免引用chp←((rpos<≢heap)∧~heap[chp],然后修改它)。试着选择一个单独而有意义的名字。平行尺寸的搁浅作业(例如(start pos)←⍵而不是start pos←⍵)。考虑使用命名约定,以及一些描述性更强的名称。(例如,我很难看出chp代表什么。)考虑在每个函数中添加注释,简要描述输入(S)和输出。https://codereview.stackexchange.com/questions/239878
复制相似问题