home *** CD-ROM | disk | FTP | other *** search
- (*Turbo/Generic - assorted procs/funcs for set operations on sets of 0..2039
- For those few of you for whom Turbo's 0..255 is too restrictive, here's
- a collection of routines that treat a 'string[255]' as a superset of 0..2039.
- There's a procedure 'show' that display a set's elements as well as a text
- message. For ease of coding, there's a routine 'Lit' that, given a normal
- set literal (i.e. [1,7,34..55,178..202]) returns a LongSet. Since you cannot
- have an element greater than 255 in normal Turbo sets, to set additional
- elements you do "S1 := SetOn(S1,1987)" which is equivalent to "s1:=s1+[1987]"
- IF Turbo handled such large numbers.
- The program contains some examples of usage. The first few examples have
- as comments the equivalent set operation expression for normal sets. The last
- dozen examples display set contents on the screen after various operations.
- It's suggested that you have a printout of the source while you're viewing
- the screen's display to get a flavor for proper usage. - Jim Keohane*)
-
- Program TSets;
-
- TYPE LongSet=STRING[255];
- LitSet= set of 0..255;
- str40=string[40];
-
- VAR S1,S2,S3:LongSet;
- i:integer;
-
- Procedure LongEnuf(I:Integer;var LS:LongSet);
- begin
- if i > length(LS) then
- begin
- FillChar(LS[succ(length(ls))],i-length(ls),0);
- ls[0]:=chr(i)
- end
- end;
-
-
- Function SetOff(LS:LongSet;I:Integer):LongSet;
- var j:integer;
- begin
- j:=1+I shr 3;
- if j> Length(LS) then LongEnuf(j,LS);
- ls[j]:=chr(ord(ls[j]) and ($ff7f shr (7-(i and $7))));
- SetOff:=ls
- end;
-
- Function SetOn(LS:LongSet;I:Integer):LongSet;
- var j:integer;
- begin
- j:=1+I shr 3;
- if j> Length(LS) then LongEnuf(j,LS);
- ls[j]:=chr(ord(ls[j]) or ($0080 shr (7-(i and $7))));
- SetOn:=ls
- end;
-
- Function InSet(I:integer;S:LongSet):boolean;
- var j:integer;
- begin
- j := 1 + i shr 3;
- if j >length(s) then InSet:=false else
- InSet:=ord(s[j]) and ($0080 shr (7-(i and $7))) <> 0
- end;
-
-
- Function Union(S1,S2:LongSet):LongSet;
- var s:longset;
- i:integer;
- begin
- s:=s1;
- if length(s1)<length(s2) then LongEnuf(length(s2),s);
- for i:=1 to length(s2) do s[i]:=chr(ord(s[i]) or ord(s2[i]));
- Union:=s
- end;
-
- Function Diff(S1,S2:LongSet):LongSet;
- var s:longset;
- i:integer;
- begin
- s:=s1;
- for i:=1 to length(s) do s[i]:=chr(ord(s[i]) and (not ord(s2[i])));
- Diff:=s
- end;
-
- Function Intersect(S1,S2:LongSet):LongSet;
- var s:longset;
- i:integer;
- begin
- if length(s1)<length(s2) then s[0]:=s1[0] else s[0]:=s2[0];
- for i:=1 to length(s) do s[i]:=chr(ord(s1[i]) and ord(s2[i]));
- while (s[0]>#0) and (s[length(s)]=#0) do s[0]:=pred(s[0]);
- Intersect:=s
- end;
-
- Function Lit(l:litset):LongSet;
- var s:longset;
- begin
- s[0]:=' ';
- move(l,s[1],32);
- while (s[0]>#0) and (s[length(s)]=#0) do s[0]:=pred(s[0]);
- Lit:=s
- end;
-
- Function Leq(S1,S2:LongSet):boolean;
- begin
- if s1=s2 then Leq:=true else
- Leq := s1 = Intersect(s1,s2)
- end;
-
- Function Geq(S1,S2:LongSet):boolean;
- begin
- if s1=s2 then Geq:=true else
- Geq := s2 = Intersect(s1,s2)
- end;
-
- Procedure Show(txt:str40;S:LongSet);
- var i,j:integer;
- begin
- j:=length(s) shl 3 -1;
- write(txt,' ':40-length(txt));
- for i:=0 to j do if inset(i,s) then write(i:8);
- writeln
- end;
-
-
- BEGIN
-
- S1 := ''; {S1 := [] }
- S1 := SetOn(S1,100); { S1 := S1 + [100] }
- S2 := S1; {straight assignment}
- IF InSet(100,S1) THEN; {IF 100 IN S1 }
- S1 := SetOff(S1,100); { S1 := S1 - [100] }
- S3 := Union(S1,S2); { S1 := S1 + S2 }
- S3 := Intersect(S1,S2); { S3 := S1 * S2 }
- S3 := Diff(S1,S2); {S3 := S1 - S2 }
- IF S2 = S3 then; {if s2 = s3 }
- IF Leq(S1,s2) then; { if s1 <= s2 }
- IF Geq(S1,S2) then; { if s1>=s2 }
- S3 := Lit([1,5,35..78,126]); { s3 := [1,5,35..78,126] }
- IF Intersect(S1,S2)='' then; { if s1*s2=[] }
-
- {test some routines}
- S1:='';
- show('null',s1);
- s1:=lit([1..5,200,232]);
- show('[1..5,200,232]',s1);
- s1:='';
- s1:=seton(s1,1);s1:=seton(s1,2);s1:=seton(s1,3);s1:=seton(s1,4);
- s1:=seton(s1,5);s1:=seton(s1,200);s1:=seton(s1,232);
- show('[1..5,200,232]',s1);
- s2:=lit([199..201]);
- s3:=union(s1,s2);
- show('[1..5,199..201,232]',s3);
- s3:=intersect(s1,s2);
- show('[200]',s3);
- show('s1=',s1);
- show('s2=',s2);
- if not geq(s1,s2) then writeln('s1 IS NOT >= s2');
- s2:=setoff(s2,199);
- s2:=setoff(s2,201);
- show('s2 is now = to ',s2);
- if geq(s1,s2) then writeln('s1 IS NOW >= s2');
- s1:='';
- for i:= 2000 to 2010 do s1:=seton(s1,i);
- show('2000 thru 2010',s1);
- s2:='';s2:=seton(s2,2005);
- s3:=diff(s1,s2);
- show('2000..2004,2006..2010',s3);
- s3:=setoff(s3,2006);
- show('2000..2004,2007..2010',s3);
- end.
-