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.