home *** CD-ROM | disk | FTP | other *** search
- { Written in TP 3.0 -- Converted to TP 5.5 08-24-89 }
- { Modified 10/4/91, due to notice of inconsistency and incorrectness }
-
- {$R-} {Range checking off}
- {$B+} {Boolean complete evaluation on}
- {$S+} {Stack checking on}
- {$I+} {I/O checking on}
-
- Program SebestaHASH;
-
- { HASHING, as was described by Sebesta's Technique (1986) but modified
-
- The function looks like this...
-
- H(key) = L + g(key[1]) + g(key[L] + Alphabetic(key[L-1])
-
- Where L is the length of the given key. g(key[x]) is the
- specific character's integer (ordinal) value and that
- Alphabetic(key[L-1]) is the numerical alphabetic position of
- the second to last charachter (1-26). Thus, "EXIT" would produce
- H("EXIT") = 4 + g("E") + g("T") + 8 = 165
-
- }
-
-
-
- CONST
- ArraySize = 71; { Note, this is a prime number and should be a prime }
-
- TYPE
- StrType = STRING[80]; { Max 80 chars per line. You can change this }
- RecType = RECORD
- Occupied : BOOLEAN;
- Name : StrType;
- END;
- ArrayType = Array [1..ArraySize] of RecType;
-
- VAR
- InString : StrType;
- Table : ArrayType;
- I,J,NumSt,Collisions : Integer;
- Occp : Integer;
-
- Function Hash(S : StrType) : INTEGER;
- Var
- L,Temp : INTEGER;
-
- Function Alpha(Ch : CHAR) : INTEGER;
- Var
- Uch : char;
- begin
- Uch := UpCase(Ch);
- If ((Uch >= 'A') and (Uch <= 'Z'))
- then Alpha := (Ord(Uch) - 64) { not 65, 'A' - 64 = 1 }
- else Alpha := Ord(Uch); { Any other ascii char gives its ascii code }
- end;
-
- BEGIN
- Temp := 0;
- L := Length(S); { Get the Length of thing }
- Temp := L + Ord(S[1]) + Ord(S[L]) + Alpha(S[L-1]);
- Temp := (Temp MOD ArraySize) + 1;
- Hash := Temp;
- END;
-
-
- BEGIN { Main }
- Collisions := 0;
- For I := 1 to ArraySize do
- Begin
- Table[I].Occupied := FALSE;
- Table[I].Name := '';
- End;
- Write('How Many Strings of chars will be inputted ? ');
- ReadLn(NumSt);
- For I := 1 to NumSt do
- Begin
- Write ('String Number ',I:4,' ? ');
- ReadLn(InString);
- WriteLn;
- J := Hash(Instring);
- IF Table[J].Occupied
- THEN
- Begin
- WriteLn('**** Collision at J=',J,' ',Instring,' and ',Table[J].Name);
- Collisions := Succ(Collisions);
- End
- ELSE
- Begin
- Table[J].Occupied := TRUE;
- Table[J].Name := Instring;
- End;
- End;
- WriteLN;
- Occp := 0;
- For I := 1 to ArraySize do
- If Table[I].Occupied then
- begin
- WriteLn('Position ',I,' STRING = "',Table[I].Name,'"');
- Occp := Succ(Occp);
- end;
- WriteLn;
- WriteLn('STATISTICS:::');
- WriteLn(Collisions,' total string allocation hash collisions.');
- Write('(', Occp,' of ',ArraySize,' array spaces occupied) ');
- WriteLn(((Occp/ArraySize)*100):3:3,'% utilization.');
- Write('(', Occp,' of ',NumSt,' input strings allocated) ');
- WriteLn(((Occp/NumSt)*100):3:3,'% utilization.');
- WriteLn;
- WriteLn('Inverted Cluster Map');
- For I := 1 to ArraySize do
- Write((I mod 10):1);
- WriteLn;
- For I := 1 to ArraySize do
- If Table[I].Occupied
- then write(chr(219))
- else write(' ');
- WriteLn;
- WriteLn('End Run.');
- END.
-