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.)
(→‎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 m.txt
* 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
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 */
Call lineout oid
Do Until wordpos(answer,'Y N')>0
Say 'file' oid 'exists. May it be replaced?'
Pull answer
End
If answer='Y' Then
'erase' oid
Else Do
Say 'Ok, we give up'
Exit
End
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 x.i<<min Then Do /* avoid numerical comparison */
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
imin=i /* next source */
min=x.i
min=x.i /* element to be used */
End
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
End
If imin<>0 Then Do /* found next source */
If min<<high Then Do
Call o x.imin
Call o x.imin /* use its element */
Call get imin
Call get imin /* get next element */
/* or set done.imin */
End
Else Do
Call lineout oid
Leave
End
End
Else /* no more elements */
Call lineout oid /* close output file */
End
End
'type' oid
Exit
Exit

get: Procedure Expose f. x. high p.
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 */
Exit
End
End
p.ii=x.ii /* remember the element */
p.ii=x.ii
End
End
Return
Return

o: Say arg(1)
Return lineout(oid,arg(1))</lang>
o: Return lineout(oid,arg(1))</lang>
{{out}}
{{out}}
<pre>1
<pre>1