home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / INFO / PASCAL / PT03.ZIP / SORTF.AR < prev    next >
Encoding:
Text File  |  1983-09-01  |  13.1 KB  |  567 lines

  1. -h- bubble.srt 300
  2. { bubble -- bubble sort v[1] ... v[n] increasing }
  3. procedure bubble (var v : intarray; n : integer);
  4. var
  5.  i, j, k : integer;
  6. begin
  7.  for i := n downto 2 do
  8.   for j := 1 to i-1 do
  9.    if (v[j] > v[j+1]) then begin { compare }
  10.     k := v[j]; { exchange }
  11.     v[j] := v[j+1];
  12.     v[j+1] := k
  13.    end
  14. end;
  15.  
  16. -h- cmp.srt 825
  17. { cmp -- compare linebuf[i] with linebuf[j] }
  18. function cmp (i, j : charpos; var linebuf : charbuf; cbeg,cend : charpos)
  19.   : integer;
  20. var ii,jj: charpos;
  21.     kk     : integer;
  22. begin
  23.  ii := 1;
  24.  while (ii < cbeg) do
  25.     if (linebuf[ii+i-1] = ENDSTR) then break
  26.     else ii := ii + 1;
  27.  i := i + ii - 1;
  28.  jj := 1;
  29.  while (jj < cbeg) do
  30.     if (linebuf[jj+j-1] = ENDSTR) then break
  31.     else jj := jj + 1;
  32.  j := j + jj - 1;
  33.  kk := cend - cbeg;
  34.  while (linebuf[i] = linebuf[j])
  35.    and (linebuf[i] <> ENDSTR) and (kk > 0) do begin
  36.   i := i + 1;
  37.   j := j + 1;
  38.   kk := kk - 1;
  39.  end;
  40.  if (linebuf[i] = linebuf[j]) then
  41.   cmp := 0
  42.  else if (linebuf[i] = ENDSTR) then { 1st is shorter }
  43.   cmp := -1
  44.  else if (linebuf[j] = ENDSTR) then { 2nd is shorter }
  45.   cmp := +1
  46.  else if (linebuf[i] < linebuf[j]) then
  47.   cmp := -1
  48.  else
  49.   cmp := +1
  50. end;
  51.  
  52. -h- cscopy.srt 247
  53. { cscopy -- copy cb[i]... to string s }
  54. procedure cscopy (var cb : charbuf; i : charpos;
  55.   var s : string);
  56. var
  57.  j : integer;
  58. begin
  59.  j := 1;
  60.  while (cb[i] <> ENDSTR) do begin
  61.   s[j] := cb[i];
  62.   i := i + 1;
  63.   j := j + 1
  64.  end;
  65.  s[j] := ENDSTR
  66. end;
  67.  
  68. -h- exchange.srt 174
  69. { exchange -- exchange linebuf[lp1] with linebuf[lp2] }
  70. procedure exchange (var lp1, lp2 : charpos);
  71. var
  72.  temp : charpos;
  73. begin
  74.  temp := lp1;
  75.  lp1 := lp2;
  76.  lp2 := temp
  77. end;
  78.  
  79. -h- gname.srt 337
  80. { gname -- generate unique name for file id n }
  81. procedure gname (n : integer; var name : string);
  82. var
  83.  junk : integer;
  84. begin
  85.  { setstring(name, 'stemp'); }
  86.   name[1] := ord('s');
  87.   name[2] := ord('t');
  88.   name[3] := ord('e');
  89.   name[4] := ord('m');
  90.   name[5] := ord('p');
  91.   name[6] := ENDSTR;
  92.  junk := itoc(n, name, length(name)+1)
  93. end;
  94.  
  95. -h- gopen.srt 249
  96. { gopen -- open group of files f1 ... f2 }
  97. procedure gopen (var infile : fdbuf; f1, f2 : integer);
  98. var
  99.  name : string;
  100.  i : 1..MERGEORDER;
  101. begin
  102.  for i := 1 to f2-f1+1 do begin
  103.   gname(f1+i-1, name);
  104.   infile[i] := mustopen(name, IOREAD)
  105.  end
  106. end;
  107.  
  108. -h- gremove.srt 253
  109. { gremove -- remove group of files f1 ... f2 }
  110. procedure gremove (var infile : fdbuf; f1, f2 : integer);
  111. var
  112.  name : string;
  113.  i : 1..MERGEORDER;
  114. begin
  115.  for i := 1 to f2-f1+1 do begin
  116.   xclose(infile[i]);
  117.   gname(f1+i-1, name);
  118.   remove(name)
  119.  end
  120. end;
  121.  
  122. -h- gtext.srt 665
  123. { gtext -- get text lines into linebuf }
  124. function gtext (var linepos : posbuf; var nlines : pos;
  125.   var linebuf : charbuf; infile : filedesc) : boolean;
  126. var
  127.  i, len, nextpos : integer;
  128.  temp : string;
  129.  done : boolean;
  130. begin
  131.  nlines := 0;
  132.  nextpos := 1;
  133.  repeat
  134.   done := (getline(temp, infile, MAXSTR) = false);
  135.   if (not done) then begin
  136.    nlines := nlines + 1;
  137.    linepos[nlines] := nextpos;
  138.    len := length(temp);
  139.    for i := 1 to len do
  140.     linebuf[nextpos+i-1] := temp[i];
  141.    linebuf[nextpos+len] := ENDSTR;
  142.    nextpos := nextpos + len + 1  { 1 for ENDSTR }
  143.   end
  144.  until (done) or (nextpos >= MAXCHARS-MAXSTR)
  145.    or (nlines >= MAXLINES);
  146.  gtext := done
  147. end;
  148.  
  149. -h- inmemqui.srt 613
  150. { sort -- sort text lines in memory }
  151. procedure inmemquick;
  152. const
  153.  MAXCHARS = 10000; { maximum # of text characters }
  154.  MAXLINES = 100;  { maximum # of line pointers }
  155. type
  156.  charpos = 1..MAXCHARS;
  157.  charbuf = array [1..MAXCHARS] of character;
  158.  posbuf = array [1..MAXLINES] of charpos;
  159.  pos = 0..MAXLINES;
  160. var
  161.  linebuf : charbuf;
  162.  linepos : posbuf;
  163.  nlines : pos;
  164. #include "gtext.p"
  165. #include "quick.p"
  166. #include "ptext.p"
  167. begin
  168.  if (gtext(linepos, nlines, linebuf, STDIN)) then begin
  169.   quick(linepos, nlines, linebuf);
  170.   ptext(linepos, nlines, linebuf, STDOUT)
  171.  end
  172.  else
  173.   error('sort: input too big to sort')
  174. end;
  175.  
  176. -h- inmemsor.srt 604
  177. { sort -- sort text lines in memory }
  178. procedure inmemsort;
  179. const
  180.  MAXCHARS = 10000; { maximum # of text characters }
  181.  MAXLINES = 300;  { maximum # of lines }
  182. type
  183.  charbuf = array [1..MAXCHARS] of character;
  184.  charpos = 1..MAXCHARS;
  185.  posbuf = array [1..MAXLINES] of charpos;
  186.  pos = 0..MAXLINES;
  187. var
  188.  linebuf : charbuf;
  189.  linepos : posbuf;
  190.  nlines : pos;
  191. #include "gtext.p"
  192. #include "shell.p"
  193. #include "ptext.p"
  194. begin
  195.  if (gtext(linepos, nlines, linebuf, STDIN)) then begin
  196.   shell(linepos, nlines, linebuf);
  197.   ptext(linepos, nlines, linebuf, STDOUT)
  198.  end
  199.  else
  200.   error('sort: input too big to sort')
  201. end;
  202.  
  203. -h- makefile.srt 175
  204. { makefile -- make new file for number n }
  205. function makefile (n : integer) : filedesc;
  206. var
  207.  name : string;
  208. begin
  209.  gname(n, name);
  210.  makefile := mustcreate(name, IOWRITE)
  211. end;
  212.  
  213. -h- merge.srt 978
  214. { merge -- merge infile[1] ... infile[nf] onto outfile }
  215. procedure merge (var infile : fdbuf; nf : integer;
  216.   outfile : filedesc; cbeg,cend :charpos);
  217. var
  218.  i, j : integer;
  219.  lbp : charpos;
  220.  temp : string;
  221. {$include:'reheap.srt'}
  222. {$include:'sccopy.srt'}
  223. {$include:'cscopy.srt'}
  224. begin
  225.  j := 0;
  226.  for i := 1 to nf do { get one line from each file }
  227.   if (getline(temp, infile[i], MAXSTR)) then begin
  228.    lbp := (i-1)*MAXSTR + 1; { room for longest }
  229.    sccopy(temp, linebuf, lbp);
  230.    linepos[i] := lbp;
  231.    j := j + 1
  232.   end;
  233.  nf := j;
  234.  quick(linepos, nf, linebuf, cbeg, cend); { make initial heap }
  235.  while (nf > 0) do begin
  236.   lbp := linepos[1]; { lowest line }
  237.   cscopy(linebuf, lbp, temp);
  238.   putstr(temp, outfile);
  239.   i := lbp div MAXSTR + 1; { compute file index }
  240.   if (getline(temp, infile[i], MAXSTR)) then
  241.    sccopy(temp, linebuf, lbp)
  242.   else begin { one less input file }
  243.    linepos[1] := linepos[nf];
  244.    nf := nf - 1
  245.   end;
  246.   reheap(linepos, nf, linebuf, cbeg, cend)
  247.  end
  248. end;
  249.  
  250. -h- ptext.srt 326
  251. { ptext -- output text lines from linebuf }
  252. procedure ptext (var linepos : posbuf; nlines : integer;
  253.   var linebuf : charbuf; outfile : filedesc);
  254. var
  255.  i, j : integer;
  256. begin
  257.  for i := 1 to nlines do begin
  258.   j := linepos[i];
  259.   while (linebuf[j] <> ENDSTR) do begin
  260.    putcf(linebuf[j], outfile);
  261.    j := j + 1
  262.   end
  263.  end
  264. end;
  265.  
  266. -h- quick.srt 200
  267. { quick -- quicksort for lines }
  268. procedure quick (var linepos : posbuf; nlines : pos;
  269.   var linebuf : charbuf; cbeg,cend : charpos);
  270. {$include:'rquick.srt'}
  271. begin
  272.  rquick(1, nlines, cbeg, cend)
  273. end;
  274.  
  275. -h- reheap.srt 566
  276. { reheap -- put linebuf[linepos[1]] in proper place in heap }
  277. procedure reheap (var linepos : posbuf; nf : pos;
  278.   var linebuf : charbuf; cbeg,cend : charpos);
  279. var
  280.  i, j : integer;
  281. begin
  282.  i := 1;
  283.  j := 2 * i;
  284.  while (j <= nf) do begin
  285.   if (j < nf) then  { find smaller child }
  286.    if (cmp(linepos[j],linepos[j+1],linebuf, cbeg, cend)>0) then
  287.     j := j + 1;
  288.   if (cmp(linepos[i], linepos[j], linebuf, cbeg, cend)<=0) then
  289.    i := nf { proper position found; terminate loop }
  290.   else
  291.    exchange(linepos[i], linepos[j]); { percolate }
  292.   i := j;
  293.   j := 2 * i
  294.  end
  295. end;
  296.  
  297. -h- rquick.srt 764
  298. { rquick -- recursive quicksort }
  299. procedure rquick (lo, hi: integer; cbeg,cend : charpos);
  300. var
  301.  i, j : integer;
  302.  pivline : charpos;
  303. begin
  304.  if (lo < hi) then begin
  305.   i := lo;
  306.   j := hi;
  307.   pivline := linepos[j]; { pivot line }
  308.   repeat
  309.    while (i < j)
  310.      and (cmp(linepos[i],pivline,linebuf,cbeg,cend) <= 0) do
  311.     i := i + 1;
  312.    while (j > i)
  313.      and (cmp(linepos[j],pivline,linebuf,cbeg,cend) >= 0) do
  314.     j := j - 1;
  315.    if (i < j) then  { out of order pair }
  316.     exchange(linepos[i], linepos[j])
  317.   until (i >= j);
  318.   exchange(linepos[i], linepos[hi]); { move pivot to i }
  319.   if (i - lo < hi - i) then begin
  320.    rquick(lo, i-1,cbeg,cend);
  321.    rquick(i+1, hi,cbeg,cend)
  322.   end
  323.   else begin
  324.    rquick(i+1, hi,cbeg,cend);
  325.    rquick(lo, i-1,cbeg,cend)
  326.   end
  327.  end
  328. end;
  329.  
  330. -h- sccopy.srt 247
  331. { sccopy -- copy string s to cb[i]... }
  332. procedure sccopy (var s : string; var cb : charbuf;
  333.   i : charpos);
  334. var
  335.  j : integer;
  336. begin
  337.  j := 1;
  338.  while (s[j] <> ENDSTR) do begin
  339.   cb[i] := s[j];
  340.   j := j + 1;
  341.   i := i + 1
  342.  end;
  343.  cb[i] := ENDSTR
  344. end;
  345.  
  346. -h- shell.srt 550
  347. { shell -- ascending Shell sort for lines }
  348. procedure shell (var linepos : posbuf; nlines : integer;
  349.   var linebuf : charbuf);
  350. var
  351.  gap, i, j, jg : integer;
  352. #include "cmp.p"
  353. #include "exchange.p"
  354. begin
  355.  gap := nlines div 2;
  356.  while (gap > 0) do begin
  357.   for i := gap+1 to nlines do begin
  358.    j := i - gap;
  359.    while (j > 0) do begin
  360.     jg := j + gap;
  361.     if (cmp(linepos[j],linepos[jg],linebuf)<=0) then
  362.      j := 0 { force loop termination }
  363.     else
  364.      exchange(linepos[j], linepos[jg]);
  365.     j := j - gap
  366.    end
  367.   end;
  368.   gap := gap div 2
  369.  end
  370. end;
  371.  
  372. -h- shell0.srt 501
  373. { shell -- Shell sort v[1]...v[n] increasing }
  374. procedure shell (var v : intarray; n : integer);
  375. var
  376.  gap, i, j, jg, k : integer;
  377. begin
  378.  gap := n div 2;
  379.  while (gap > 0) do begin
  380.   for i := gap+1 to n do begin
  381.    j := i - gap;
  382.    while (j > 0) do begin
  383.     jg := j + gap;
  384.     if (v[j] <= v[jg]) then  { compare }
  385.      j := 0 { force loop termination }
  386.     else begin
  387.      k := v[j]; { exchange }
  388.      v[j] := v[jg];
  389.      v[jg] := k
  390.     end;
  391.     j := j - gap
  392.    end
  393.   end;
  394.   gap := gap div 2
  395.  end
  396. end;
  397.  
  398. -h- sort.srt 1717
  399. { sort -- external sort of text lines }
  400. procedure sort;
  401. const
  402.  MAXCHARS = 10000; { maximum # of text characters }
  403.  MAXLINES = 300;  { maximum # of lines }
  404.  MERGEORDER = 5;
  405. type
  406.  charpos = 1..MAXCHARS;
  407.  charbuf = array [1..MAXCHARS] of character;
  408.  posbuf = array [1..MAXLINES] of charpos;
  409.  pos = 0..MAXLINES;
  410.  fdbuf = array [1..MERGEORDER] of filedesc;
  411. var
  412.  linebuf : charbuf;
  413.  linepos : posbuf;
  414.  nlines : pos;
  415.  infile : fdbuf;
  416.  outfile : filedesc;
  417.  high, low, lim : integer;
  418.  done : boolean;
  419.  name : string;
  420.  cbeg,cend : charpos;      { start/end of chars to be compared }
  421.  arg: string;
  422.  i  : integer;
  423. {$include:'sortproc.srt'}
  424. begin
  425.  { get beg/end positions to be sorted, if any }
  426.  cbeg := 1;
  427.  cend := MAXSTR;
  428.  if (getarg(1,arg,MAXSTR)) then begin
  429.     i := 1;
  430.     cbeg := ctoi(arg,i);
  431.     if (getarg(2,arg,MAXSTR)) then begin
  432.        i := 1;
  433.        cend := ctoi(arg,i);
  434.        end;
  435.     if (cbeg <= 0) or (cend <= 0) or (cend < cbeg) then
  436.        error('Invalid Argument. Syntax: sort [startpos] [endpos]');
  437.     end;
  438.  high := 0;
  439.  repeat { initial formation of runs }
  440.   done := gtext(linepos, nlines, linebuf, STDIN);
  441.   quick(linepos, nlines, linebuf, cbeg, cend);
  442.   high := high + 1;
  443.   outfile := makefile(high);
  444.   ptext(linepos, nlines, linebuf, outfile);
  445.   xclose(outfile)
  446.  until (done);
  447.  low := 1;
  448.  while (low < high) do begin { merge runs }
  449.   lim := imin(low+MERGEORDER-1, high);
  450.   gopen(infile, low, lim);
  451.   high := high + 1;
  452.   outfile := makefile(high);
  453.   merge(infile, lim-low+1, outfile, cbeg, cend);
  454.   xclose(outfile);
  455.   gremove(infile, low, lim);
  456.   low := low + MERGEORDER
  457.  end;
  458.  gname(high, name); { final cleanup }
  459.  outfile := open(name, IOREAD);
  460.  fcopy(outfile, STDOUT);
  461.  xclose(outfile);
  462.  remove(name)
  463. end;
  464.  
  465. -h- sortproc.srt 297
  466. { sortproc -- procedures for sort }
  467. {$include:'cmp.srt'     }
  468. {$include:'exchange.srt'}
  469. {$include:'gtext.srt'   }
  470. {$include:'ptext.srt'   }
  471. {$include:'quick.srt'   }
  472. {$include:'gname.srt'   }
  473. {$include:'makefile.srt'}
  474. {$include:'gopen.srt'   }
  475. {$include:'merge.srt'   }
  476. {$include:'gremove.srt' }
  477.  
  478. -h- sortquic.srt 619
  479. { sort -- sort text lines in memory }
  480. procedure sort;
  481. const
  482.  MAXCHARS = 1000; { maximum number of text characters }
  483.  MAXLINES = 100; { maximum number of line pointers }
  484. type
  485.  charpos = 1..MAXCHARS;
  486.  charbuf = array [1..MAXCHARS] of character;
  487.  posbuf = array [1..MAXLINES] of charpos;
  488.  pos = 0..MAXLINES;
  489. var
  490.  linbuf : charbuf;
  491.  linpos : posbuf;
  492.  nlines : pos;
  493.  
  494. #include "gtext.p"
  495. #include "quick.p"
  496. #include "ptext.p"
  497.  
  498. begin
  499.  if (gtext(linpos, nlines, linbuf, STDIN) = ENDFILE) then begin
  500.   quick(linpos, nlines, linbuf);
  501.   ptext(linpos, nlines, linbuf, STDOUT)
  502.  end
  503.  else
  504.   error('sort: input too big to sort')
  505. end;
  506.  
  507. -h- sorttest.srt 353
  508. procedure sorttest;
  509. type intarray = array [1..100] of integer;
  510. var
  511.  v : intarray;
  512.  buf : string;
  513.  i, j : integer;
  514. #include "shell0.p"
  515. #include "ctoi.p"
  516. begin
  517.  j := 0;
  518.  while (getline(buf, STDIN, MAXSTR)) do begin
  519.   j := j + 1;
  520.   i := 1;
  521.   v[j] := ctoi(buf, i)
  522.   end;
  523.  shell(v, j);
  524.  for i := 1 to j do begin
  525.   putdec(v[i], 1);
  526.   putc(NEWLINE)
  527.  end
  528. end;
  529.  
  530. -h- sortf.pas 611
  531. {$debug-}
  532. program outer (input,output);
  533.  
  534. {$include:'globcons.inc'}
  535. {$include:'globtyps.inc'}
  536.  
  537. {$include:'initio.dcl'}
  538. {$include:'flush.dcl' }
  539.  
  540. {$include:'getarg.dcl'  }
  541. {$include:'ctoi.dcl'    }
  542. {$include:'error.dcl'   }
  543. {$include:'getline.dcl' }
  544. {$include:'putcf.dcl'   }
  545. {$include:'itoc.dcl'    }
  546. {$include:'length.dcl'  }
  547. {$include:'mustcrea.dcl'}
  548. {$include:'mustopen.dcl'}
  549. {$include:'open.dcl'    }
  550. {$include:'putstr.dcl'  }
  551. {$include:'remove.dcl'  }
  552. {$include:'close.dcl'   }
  553. {$include:'fcopy.dcl'   }
  554. {$include:'imin.dcl'    }
  555.  
  556.  
  557. {$include:'sort.srt'    }
  558. BEGIN
  559.   minitio; initio;
  560.   sort;
  561.   flush(0);
  562. END.
  563. -h- sortf.mak 165
  564. sortf+initio+getfcb+error+getarg+nargs+length+getline+
  565. getcf+getc+putstr+putc+putcf+itoc+mustcreate+create+
  566. remove+close+fcopy+mustopen+open+imin+flush+ctoi+isdigit
  567.