Task: Stream merge





Java: import java.util.Iterator;
import java.util.List;
import java.util.Objects;

public class StreamMerge {
    private static <T extends Comparable<T>> void merge2(Iterator<T> i1, Iterator<T> i2) {
        T a = null, b = null;

        while (i1.hasNext() || i2.hasNext()) {
            if (null == a && i1.hasNext()) {
                a = i1.next();
            }
            if (null == b && i2.hasNext()) {
                b = i2.next();
            }

            if (null != a) {
                if (null != b) {
                    if (a.compareTo(b) < 0) {
                        System.out.print(a);
                        a = null;
                    } else {
                        System.out.print(b);
                        b = null;
                    }
                } else {
                    System.out.print(a);
                    a = null;
                }
            } else if (null != b) {
                System.out.print(b);
                b = null;
            }
        }

        if (null != a) {
            System.out.print(a);
        }
        if (null != b) {
            System.out.print(b);
        }
    }

    @SuppressWarnings("unchecked")
    @SafeVarargs
    private static <T extends Comparable<T>> void mergeN(Iterator<T>... iter) {
        Objects.requireNonNull(iter);
        if (iter.length == 0) {
            throw new IllegalArgumentException("Must have at least one iterator");
        }

        Object[] pa = new Object[iter.length];
        boolean done;

        do {
            done = true;

            for (int i = 0; i < iter.length; i++) {
                Iterator<T> t = iter[i];
                if (null == pa[i] && t.hasNext()) {
                    pa[i] = t.next();
                }
            }

            T min = null;
            int idx = -1;
            for (int i = 0; i < pa.length; ++i) {
                T t = (T) pa[i];
                if (null != t) {
                    if (null == min) {
                        min = t;
                        idx = i;
                        done = false;
                    } else if (t.compareTo(min) < 0) {
                        min = t;
                        idx = i;
                        done = false;
                    }
                }
            }
            if (idx != -1) {
                System.out.print(min);
                pa[idx] = null;
            }
        } while (!done);
    }

    public static void main(String[] args) {
        List<Integer> l1 = List.of(1, 4, 7, 10);
        List<Integer> l2 = List.of(2, 5, 8, 11);
        List<Integer> l3 = List.of(3, 6, 9, 12);

        merge2(l1.iterator(), l2.iterator());
        System.out.println();

        mergeN(l1.iterator(), l2.iterator(), l3.iterator());
        System.out.println();
        System.out.flush();
    }
}






Fortran:       SUBROUTINE FILEMERGE(N,INF,OUTF)	
       INTEGER N	
       INTEGER INF(*)	
       INTEGER OUTF	
       INTEGER L(N)	
       INTEGER LIST(0:N)
       LOGICAL LIVE(N)	
       INTEGER ENUFF		
       PARAMETER (ENUFF = 666)	
       CHARACTER*(ENUFF) AREC(N)
       INTEGER I,IT	
        LIST = 0	
        LIVE = .TRUE.	
Charge the battery.
        DO I = 1,N	
          CALL GRAB(I)		
        END DO		
Chug away.
        DO WHILE(LIST(0).GT.0)	
          IT = LIST(0)		
          WRITE (OUTF,"(A)") AREC(IT)(1:L(IT))	
          LIST(0) = LIST(IT)	
          CALL GRAB(IT)		
        END DO			

       CONTAINS	
        SUBROUTINE GRAB(IN)	
         INTEGER IN		
         INTEGER IT,P		
          IF (.NOT.LIVE(IN)) RETURN	
          READ (INF(IN),1,END = 10) L(IN),AREC(IN)(1:MIN(ENUFF,L(IN)))	
    1     FORMAT (Q,A)		
Consider the place of AREC(IN) in the LIST. Entry LIST(IN) is to be linked back in.
          P = 0		
    2     IT = LIST(P)		
          IF (IT.GT.0) THEN	
            IF (AREC(IN)(1:L(IN)).GT.AREC(IT)(1:L(IT))) THEN	
              P = IT			
              GO TO 2			
            END IF		
          END IF	
          LIST(IN) = IT		
          LIST(P) = IN		
          RETURN	
   10     LIVE(IN) = .FALSE.	
          LIST(IN) = -666	
        END SUBROUTINE GRAB	
      END SUBROUTINE FILEMERGE	

      PROGRAM MASH
      INTEGER MANY
      PARAMETER (MANY = 4)	
      INTEGER FI(MANY)
      CHARACTER*(28) FNAME(MANY)
      DATA FNAME/"FileAppend.for","FileChop.for",
     1 "FileExt.for","FileHack.for"/
      INTEGER I,F

      F = 10	
      OPEN (F,FILE="Merged.txt",STATUS="REPLACE",ACTION="WRITE")	
      DO I = 1,MANY	
        FI(I) = F + I		
        OPEN (FI(I),FILE=FNAME(I),STATUS="OLD",ACTION="READ")	
      END DO		

      CALL FILEMERGE(MANY,FI,F)	

      END