PROGRAM 4
-- Filename: prog3.adb Author: Anthony F. Ortiz
WITH Text_IO; USE Text_IO;
WITH Direct_IO;
PROCEDURE Ch7P1 is
-- Input : A test file of key values
-- Output: A direct nontext file of hashed key values
-- and synonyms.
-- The output file is first skeletonized.
SUBTYPE Key_Type Is String (1..3);
TYPE Relative_Record_Type Is Record
key : Key_Type;
synonym: integer;
End Record;
PACKAGE Key_IO Is New Direct_IO (Relative_Record_Type);
PACKAGE Positive_IO Is New Text_IO.Integer_IO (Key_IO.Positive_Count);
PACKAGE Int_IO is new Integer_IO (Integer); use Int_IO;
Use Key_IO;
MAX : Constant Key_IO.Positive_Count := 7;
address : Key_IO.Positive_Count;
home : Key_IO.Positive_Count;
input_file : Text_IO.File_Type;
input_file_record : Relative_Record_Type;
last : Natural;
record_position : Key_IO.Positive_Count;
relative_file : Key_IO.File_Type;
relative_record : Relative_Record_Type;
hold_record : Relative_Record_Type;
change_record : Relative_Record_Type;
FUNCTION Hash (key : Key_Type) Return Key_IO.Positive_Count Is
BEGIN
Return Key_IO.Positive_Count (Character'Pos (key (2))
- Character'Pos ('0'));
END Hash;
BEGIN -- Ch7P1
-- Skeletonize relative file.
Key_IO.Create (relative_file, Key_IO.OUT_FILE, "A:RELTEST.DAT");
relative_record.key := "~~~";
relative_record.synonym := -1;
For record_position In 1..MAX Loop
Key_IO.Write (relative_file, relative_record, record_position);
End Loop;
Key_IO.Close (relative_file);
-- Insert records.
Key_IO.Open (relative_file, Key_IO.INOUT_FILE, "A:RELTEST.DAT");
Text_IO.Open (input_file, Text_IO.IN_FILE, "A:HASHIN.TXT");
Text_IO.Put_Line ("KEY => ADDRESS");
Text_IO.New_Line;
Loop
Exit When Text_IO.End_of_File (input_file);
Text_IO.Get_Line (input_file, input_file_record.key, last);
Text_IO.Skip_Line (input_file);
address := Hash (input_file_record.key);
home := address;
Text_IO.Put (input_file_record.key);
Text_IO.Put (" => ");
Positive_IO.Put (address, 2);
Text_IO.New_Line;
Loop
Key_IO.Read (relative_file, relative_record, address);
If home = address then
hold_record.synonym := relative_record.synonym;
hold_record.key := relative_record.key;
End If;
If relative_record.key = "~~~" Then
input_file_record.synonym := hold_record.synonym;
Key_IO.Write (relative_file, input_file_record, address);
Exit;
Else
-- Use linear probing.
address := address + 1;
If address > MAX Then
address := 1;
End If;
-- Write the old file back with the synonym changed.
change_record.synonym := integer (address);
change_record.key := hold_record.key;
Key_IO.Write (relative_file, change_record, home);
End If;
Exit When address = home;
End Loop;
End Loop;
Text_IO.Close (input_file);
Text_IO.New_Line;
-- List file back.
Key_IO.Reset (relative_file, Key_IO.IN_FILE);
record_position := 1;
Text_IO.Put_Line (" # KEY SYNONYM");
Text_IO.New_Line;
Loop
Exit When Key_IO.End_of_File (relative_file);
Key_IO.Read (relative_file, relative_record);
Positive_IO.Put (record_position, 2);
Text_IO.Put (" ");
Text_IO.Put (relative_record.key);
Put (relative_record.synonym, 10);
Text_IO.New_Line;
record_position := record_position + 1;
End Loop;
Key_IO.Close (relative_file);
END Ch7P1;
-- data file: hashin.txt
R5A
R3A
R2A
R3B
R7A
R4A
R3C.
-- data file: reltest.dat
-- this is not a text file.
-- outfile: prog3.out
KEY => ADDRESS
R5A => 5
R3A => 3
R2A => 2
R3B => 3
R7A => 7
R4A => 4
R3C => 3
# KEY SYNONYM
1 R3C 4
2 R2A -1
3 R3A 1
4 R3B 6
5 R5A -1
6 R4A -1
7 R7A -1
BACK TO CS3660 PAGE.