home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Fred Fish Collection 1.5
/
ffcollection-1-5-1992-11.iso
/
ff_disks
/
300-399
/
ff339.lzh
/
PCQ
/
Examples
/
Counter2.p
< prev
next >
Wrap
Text File
|
1990-03-19
|
3KB
|
143 lines
Program Counter2;
{
This program reads a text file, then prints a report telling
you all the words in the file, and how many times each was
used. It was intended as a demonstration and test of string
stuff and some addressing things. The other major reason I
wrote it is because I am currently re-writing the compiler's
symbol table stuff, and the two designs I'm thinking about are
binary trees and hash tables. I am going to use the hash
tables, but I wanted to get familiar with both methods before
I started the actual work. This program uses the hash tables.
}
{$I ":Include/Ports.i"}
{$I ":Include/Parameters.i"}
{$I ":Include/StringLib.i"}
const
TableSize = 511;
type
WordRec = Record
Next : ^WordRec;
Count : Integer;
Data : array [0..255] of char;
end;
WordPtr = ^WordRec;
var
Table : Array [0..TableSize] of WordPtr;
CurrentChar : Char;
InFile : Text;
CurrentWord : String;
TotalWords : Integer;
Procedure ReadChar;
begin
if eof(InFile) then
CurrentChar := Chr(0)
else
Read(Infile, CurrentChar);
end;
Procedure SkipWhiteSpace;
begin
while (not eof(Infile)) and (not isalpha(CurrentChar)) do
ReadChar;
end;
Procedure ReadWord;
var
i : Integer;
begin
i := 0;
while isalnum(CurrentChar) do begin
CurrentWord[i] := CurrentChar;
i := Succ(i);
ReadChar;
end;
CurrentWord[i] := Chr(0);
end;
Procedure EnterWord(rec : WordPtr);
var
Result : Short;
begin
Result := Hash(Adr(rec^.Data)) and TableSize;
rec^.Next := Table[Result];
Table[Result] := rec;
end;
Procedure AddWord(str : String);
var
rec : WordPtr;
begin
rec := WordPtr(AllocString(13 + strlen(str)));
strcpy(Adr(rec^.Data), str);
rec^.Count := 1;
EnterWord(rec);
end;
Function FindWord(str : String) : WordPtr;
var
Current : WordPtr;
begin
Current := Table[Hash(str) and TableSize];
while Current <> nil do begin
if strieq(str, Adr(Current^.Data)) then
FindWord := Current;
Current := Current^.Next;
end;
FindWord := nil;
end;
Procedure Report;
var
i : Short;
W : WordPtr;
begin
for i := 0 to TableSize do begin
W := Table[i];
while W <> nil do begin
Writeln(W^.Count, Chr(9), String(Adr(W^.Data)));
TotalWords := TotalWords + W^.Count;
W := W^.Next;
end
end
end;
var
W : WordPtr;
FileName : String;
index : Integer;
begin
for index := 0 to TableSize do
Table[index] := nil;
CurrentWord := AllocString(128);
FileName := AllocString(80);
GetParam(1, FileName);
if FileName^ = Chr(0) then begin
Writeln('Usage: Counter2 FileName');
Exit(10);
end;
if reopen(FileName, Infile) then begin
SkipWhiteSpace;
while not eof(Infile) do begin
ReadWord;
SkipWhiteSpace;
W := FindWord(CurrentWord);
if W = nil then
AddWord(CurrentWord)
else
W^.Count := Succ(W^.Count);
end;
TotalWords := 0;
Report;
Writeln('Total Words: ', TotalWords);
Close(Infile);
end else
Writeln('Could not open the input file : ', FileName);
end.