Priority queue: Difference between revisions
Content added Content deleted
(SAS: Add error test for the revised %HeapPop macro) |
(Update SAS: show example using proc ds2) |
||
Line 5,629: | Line 5,629: | ||
=={{header|SAS}}== |
=={{header|SAS}}== |
||
Using macros in a SAS data step: |
Using macros in a SAS data step: |
||
<lang sas> |
<lang sas>%macro HeapInit(size=1000,nchar=20); |
||
%macro HeapInit(size=1000,nchar=20); |
|||
do; |
do; |
||
_len = 0; |
_len = 0; |
||
Line 5,725: | Line 5,724: | ||
%HeapPop; |
%HeapPop; |
||
end; |
end; |
||
run; |
run;</lang> |
||
</lang> |
|||
{{output}} |
{{output}} |
||
<pre>1 Solve RC tasks |
<pre>1 Solve RC tasks |
||
Line 5,734: | Line 5,732: | ||
5 Make tea</pre> |
5 Make tea</pre> |
||
An implementation using <code>proc ds2</code> may be more structured: |
|||
<lang sas>proc ds2; |
|||
<code>%HeapSwapItem</code>, <code>%HeapSiftdown</code> and <code>%HeapSiftup</code> macros and replace |
|||
package Heap / overwrite=yes; |
|||
the <code>%HeapPush</code> and <code>%HeapPop</code> macros. For the test code, we get the same output. |
|||
dcl int _entryorder _size _len _entryOrders[1000]; |
|||
<lang sas> |
|||
dcl double _times[1000]; |
|||
proc fcmp outlib=sasuser.funcs.trial; |
|||
dcl varchar(20) _kinds[1000]; |
|||
subroutine HeapSwapItem(index1, index2, _times[*], _kinds[*] $); |
|||
method init(); |
|||
outargs _times, _kinds; |
|||
_entryOrder = 1; |
|||
length tempC $ 20; |
|||
_size = 1000; |
|||
tempN = _times[index1]; _times[index1] = _times[index2]; _times[index2]= tempN; |
|||
_len = 0; |
|||
tempC = _kinds[index1]; _kinds[index1] = _kinds[index2]; _kinds[index2]= tempC; |
|||
endsub; |
|||
subroutine HeapSiftdown(index, _len, _times[*],_kinds[*] $); |
|||
outargs _times, _kinds; |
|||
parent = index; |
|||
done = 0; |
|||
do while (parent*2 <= _len and ^done); |
|||
child = parent*2; |
|||
if (child+1 <= _len and %HeapCompare(child+1,child)) then |
|||
child = child + 1; |
|||
if %HeapCompare(child,parent) then do; |
|||
call HeapSwapItem(child,parent, _times, _kinds); |
|||
parent = child; |
|||
end; |
|||
else done = 1; |
|||
end; |
end; |
||
method empty() returns int; |
|||
endsub; |
|||
return(_len=0); |
|||
subroutine HeapSiftup(index, _len, _times[*], _kinds[*] $); |
|||
end; |
|||
outargs _times, _kinds; |
|||
method compare(int index1, int index2) returns int; |
|||
child = index; |
|||
return(_times[index1] < _times[index2] or (_times[index1] = _times[index2] and _entryOrders[index1] < _entryOrders[index2])); |
|||
done = 0; |
|||
end; |
|||
do while(child>1 and ^done); |
|||
method SetItem(int index, double _time, int entryOrder, varchar(20) kind); |
|||
parent = floor(child/2); |
|||
_times[index] = _time; |
|||
if %HeapCompare(parent,child) then |
|||
_entryOrders[index] = entryOrder; |
|||
done = 1; |
|||
_kinds[index] = kind; |
|||
else do; |
|||
end; |
|||
call HeapSwapItem(child,parent, _times, _kinds); |
|||
method CopyItem(int ito, int ifrom); |
|||
tempN = child; |
|||
_times[ito] = _times[ifrom]; |
|||
child = parent; |
|||
_entryOrders[ito] = _entryOrders[ifrom]; |
|||
parent = tempN; |
|||
_kinds[ito] = _kinds[ifrom]; |
|||
end; |
|||
method SwapItem(int index1, int index2); |
|||
dcl double tempD; |
|||
dcl int tempI; |
|||
dcl varchar(20) tempC; |
|||
tempD = _times[index1]; _times[index1] = _times[index2]; _times[index2]= tempD; |
|||
tempI = _entryorders[index1]; _entryorders[index1] = _entryorders[index2]; _entryorders[index2]= tempI; |
|||
tempC = _kinds[index1]; _kinds[index1] = _kinds[index2]; _kinds[index2]= tempC; |
|||
end; |
|||
method Siftdown(int index); |
|||
dcl int parent done child; |
|||
parent = index; |
|||
done = 0; |
|||
do while (parent*2 <= _len and ^done); |
|||
child = parent*2; |
|||
if (child+1 <= _len and Compare(child+1,child)) then |
|||
child = child + 1; |
|||
if Compare(child,parent) then do; |
|||
SwapItem(child,parent); |
|||
parent = child; |
|||
end; |
|||
else done = 1; |
|||
end; |
end; |
||
end; |
end; |
||
method Siftup(int index); |
|||
endsub; |
|||
dcl int parent child done tempI; |
|||
run; |
|||
child = index; |
|||
options cmplib=sasuser.funcs; |
|||
done = 0; |
|||
%macro HeapPop; |
|||
do while(child>1 and ^done); |
|||
do; |
|||
parent = floor(child/2); |
|||
if _len >= _size then do; |
|||
if Compare(parent,child) then |
|||
put "ERROR: exceeded size of heap. Consider changing size argument to %HeapInit."; |
|||
done = 1; |
|||
else do; |
|||
SwapItem(child,parent); |
|||
tempI = child; |
|||
child = parent; |
|||
parent = tempI; |
|||
end; |
|||
end; |
end; |
||
end; |
|||
method Pop(); |
|||
_len = _len - 1; |
_len = _len - 1; |
||
if (_len>0) then do; |
if (_len>0) then do; |
||
CopyItem(1,_len+1); |
|||
Siftdown(1); |
|||
_kinds[1] = _kinds[_len+1]; |
|||
call HeapSiftdown(1, _len, _times, _kinds); |
|||
end; |
end; |
||
end; |
end; |
||
method PeekTime() returns double; |
|||
%mend; |
|||
return _times[1]; |
|||
%macro HeapPush(time, kind); |
|||
end; |
|||
method PeekKind() returns varchar(20); |
|||
return _kinds[1]; |
|||
end; |
|||
method Push(double _time, varchar(20) kind); |
|||
if _len >= _size then do; |
|||
put 'ERROR: exceeded size of heap.'; |
|||
stop; |
|||
end; |
|||
_len = _len + 1; |
_len = _len + 1; |
||
_entryOrder = _entryOrder + 1; |
|||
_times[_len] = &time; |
|||
SetItem(_len, _time, _entryOrder, kind); |
|||
Siftup(_len); |
|||
call HeapSiftup(_len, _len, _times, _kinds); |
|||
end; |
end; |
||
endpackage; |
|||
%mend; |
|||
run; |
|||
</lang> |
|||
data _null_; |
|||
dcl package Heap h(); |
|||
method init(); |
|||
dcl double _time; |
|||
dcl varchar(20) _kind; |
|||
h.init(); |
|||
h.Push(3, 'Clear drains'); |
|||
h.Push(4, 'Feed cat'); |
|||
h.Push(5, 'Make tea'); |
|||
h.Push(1, 'Solve RC tasks'); |
|||
h.Push(2, 'Tax return'); |
|||
do while(^h.empty()); |
|||
_time = h.PeekTime(); |
|||
_kind = h.PeekKind(); |
|||
put _time _kind; |
|||
h.Pop(); |
|||
end; |
|||
end; |
|||
enddata; |
|||
run;</lang> |
|||
=={{header|Scala}}== |
=={{header|Scala}}== |