Stream merge: Difference between revisions
Content added Content deleted
(→version 2: changed program so that it can run under PC/REXX and Personal REXX, also insured that running a 2nd time doesn't corrupt the output file.) |
Walterpachl (talk | contribs) (→REXX version 1: reworked considering Gerard Schildberger's comments) |
||
Line 1,833: | Line 1,833: | ||
== {{header|REXX}} == |
== {{header|REXX}} == |
||
===version 1=== |
===version 1=== |
||
<lang rexx>/* |
<lang rexx>/* REXX *************************************************************** |
||
* Merge 1.txt ... n.txt into |
* Merge 1.txt ... n.txt into all.txt |
||
* 1.txt 2.txt 3.txt 4.txt |
* 1.txt 2.txt 3.txt 4.txt |
||
* 1 19 1999 2e3 |
* 1 19 1999 2e3 |
||
* 17 33 2999 3000 |
* 17 33 2999 3000 |
||
* 8 500 3999 |
* 8 500 3999 RC task STREAM MERGE |
||
**********************************************************************/ |
**********************************************************************/ |
||
done.=0 /* done.i=1 indicates file exhausted */ |
|||
n=4 |
|||
p.='' /* for test of sort error */ |
|||
high='ffff'x |
|||
Do i=1 By 1 /* check files for existence */ |
|||
p.='' |
|||
Do i=1 To n |
|||
f.i=i'.txt' |
f.i=i'.txt' |
||
If lines(f.i)=0 Then Leave |
|||
⚫ | |||
Call get i /* and read first line of each*/ |
|||
End |
End |
||
n=i-1 /* we have n input files */ |
|||
Do Forever |
|||
done.0=n /* and all must be used */ |
|||
min=high |
|||
say n 'Input files' |
|||
oid='all.txt' |
|||
If lines(oid)>0 Then Do /* output file exists */ |
|||
⚫ | |||
Do Until wordpos(answer,'Y N')>0 |
|||
Say 'file' oid 'exists. May it be replaced?' |
|||
Pull answer |
|||
⚫ | |||
⚫ | |||
'erase' oid |
|||
⚫ | |||
Say 'Ok, we give up' |
|||
⚫ | |||
⚫ | |||
End |
|||
say oid 'is the output file' /* we'll create it now */ |
|||
Do Until done.0=0 |
|||
imin=0 /* index of next source */ |
|||
Do i=1 To n |
Do i=1 To n |
||
If |
If done.i=0 Then Do /* file i still in use */ |
||
If imin=0 Then Do /* it's the first in this loop*/ |
|||
⚫ | |||
imin=i /* next source */ |
|||
⚫ | |||
min=x.i /* element to be used */ |
|||
⚫ | |||
Else Do /* not the first */ |
|||
If x.i<<min Then Do /* avoid numerical comparison */ |
|||
imin=i /* next source */ |
|||
min=x.i /* element to be used */ |
|||
⚫ | |||
End |
|||
End |
End |
||
End |
End |
||
If imin<>0 Then Do /* found next source */ |
|||
⚫ | |||
Call o x.imin |
Call o x.imin /* use its element */ |
||
Call get imin |
Call get imin /* get next element */ |
||
/* or set done.imin */ |
|||
⚫ | |||
⚫ | |||
Call lineout oid |
|||
⚫ | |||
End |
End |
||
Else /* no more elements */ |
|||
Call lineout oid /* close output file */ |
|||
End |
End |
||
'type' oid |
|||
Exit |
Exit |
||
get: Procedure Expose f. x. |
get: Procedure Expose f. x. p. done. |
||
/********************************************************************* |
|||
* Get next element from file ii or set done.ii=1 if file is exhausted |
|||
*********************************************************************/ |
|||
Parse Arg ii |
Parse Arg ii |
||
If lines(f.ii)=0 Then |
If lines(f.ii)=0 Then Do /* file ii is exhausted */ |
||
done.ii=1 /* mark it as done */ |
|||
x.ii=high |
|||
done.0=done.0-1 /* reduce number of files tbd*/ |
|||
Else Do |
|||
End |
|||
x.ii=linein(f.ii) |
|||
Else Do /* there's more in file ii */ |
|||
If x.ii<<p.ii Then Do |
|||
x.ii=linein(f.ii) /* get next element (line) */ |
|||
If x.ii<<p.ii Then Do /* smaller than previous */ |
|||
Say 'Input file' f.ii 'is not sorted ascendingly' |
Say 'Input file' f.ii 'is not sorted ascendingly' |
||
Say p.ii 'precedes' x.ii |
Say p.ii 'precedes' x.ii /* tell the user */ |
||
Exit /* and give up */ |
|||
⚫ | |||
End |
End |
||
p.ii=x.ii /* remember the element */ |
|||
p.ii=x.ii |
|||
End |
End |
||
Return |
Return |
||
o: Say arg(1) |
|||
o: Return lineout(oid,arg(1))</lang> |
|||
{{out}} |
{{out}} |
||
<pre>1 |
<pre>1 |