Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 21.04.2010, 00:46   #1
pwdan
 
Регистрация: 24.03.2010
Сообщений: 4
По умолчанию Хеш-функция

Задача такая: осуществить поиск в телефонном справочнике с помощью хэш-функции. Данные берутся из файла. Возникла проблема с загрузкой данных из файла в хеш-таблицу. Вот код программы. Объясните, пожалуйста, в чем ошибка в функции загрузки из файла и как ее исправить. Спасибо.

Код:
program Project1;

{$APPTYPE CONSOLE}

uses
 SysUtils;

const
  HTableLen=300;
  PhoneLen=6;
  FIOLen=30;

type
  TPhone=String[PhoneLen];
  TFIO=String[FIOLen];
  TInfo=record
    Phone: TPhone;
    FIO: TFIO;
  end;

  THashItem=record
    Info: TInfo;
    used: Boolean;
  end;

  THashTable=record 
    Size: Integer;
    H: array [0..HTableLen-1] of THashItem;
  end;

  TypFile=File of THashItem;

var
  H: THashTable;
  Inform: TInfo;
  Phone: TPhone;
  x: Integer;

function ValidPhone(Phone: TPhone):Boolean;
var
  i: Integer;
begin
  if Length(Phone)=PhoneLen then
  begin
    i:=0;
    while (i<PhoneLen) or (Phone[i] in ['0'..'9']) do
      i:=i+1;
    Result:=i>PhoneLen
  end
  else
    Result:=False;
end;

procedure InputPhone(var Phone: TPhone);
begin
  while not ValidPhone(Phone) do
    Write('Введите телефон ');
    ReadLn(Phone);
end;

procedure InputInfo(var Info:TInfo);
begin
  InputPhone(Info.Phone);
  Write('Введите ФИО ');
  ReadLn(Info.FIO);
end;

procedure HashInit(var HTable: THashTable);
var
  i: Integer;
begin
  HTable.Size:=0;
  for i:=0 to HTableLen-1 do
    HTable.H[i].used:=False;
end;

function HashKey(Phone: TPhone): Integer;
begin
   Result:=(Ord(Phone[1])*100+Ord(Phone[2])*10+Ord(Phone[3])+
   Ord(Phone[4])*100+Ord(Phone[5])*10+Ord(Phone[6])) mod HTableLen;
end;

//Поиск
function HashFind(var HTable: THashTable; Phone: TPhone; var Info: TInfo): Boolean;
var
  i: Integer;
begin
  i:=HashKey(Phone);
  while HTable.H[i].used and (HTable.H[i].Info.Phone<>Phone) do
    i:=(i+1) mod HTableLen;
  if HTable.H[i].used then
  begin
    Info:=HTable.H[i].Info;
    Result:=True;
  end
  else
    Result:=False;
end;

//Вставка
function HashAdd(var HTable:THashTable; Info: TInfo): Boolean;
var
  Inf: TInfo;
  i: Integer;
begin
  if (HTable.Size=HTableLen-1) or HashFind(HTable, Info.Phone, inf) then
    Result:=False
  else
  begin
    i:=HashKey(Info.Phone);
    while HTable.H[i].used do
      i:=(i+1) mod HTableLen;
      HTable.H[i].used:=True;
      HTable.H[i].Info:=Info;
      HTable.Size:=HTable.Size+1;
  end;
end;

//Ввод данных в хэш-твблицу
procedure Input(var HTable:THashTable; Info: TInfo);
begin
  if HashAdd(HTable, Info) then
    WriteLn('Запись в хэш-таблицу прошла успешно')
  else
    WriteLn('Операция записи в хэш-таблицу отклонена');
end;


procedure NewInfo(var stat: THashTable; Info: TInfo; var n:Integer);
var
  i:Integer;
begin
  Write('Введите количество записей=');
  Readln(n);
  for i:=1 to n do
  begin
    WriteLn('Телефон и ФИО');
    Readln(stat.H[i].Info.Phone, stat.H[i].Info.FIO);
  end;
end;

//данные в файл
procedure TablToFile(var stat: THashTable; var n:Integer; const FileName: String);
var
  F: TypFile;
  i:Integer;
begin
  Assign(F, FileName);
  ReWrite(F);
  for i:=1 to n do
    Write(F, stat.H[i]);
  Close(F);
end;

//данные из файла. Эта функция не работает!
function FileToTabl(Info: TInfo; const FileName: String): THashTable;
var
  f: TypFile;
  i:integer;
begin
  Assign(F, FileName);
  Reset (F);
  WriteLn('Содержимое хэш-таблицы:');
  while not EOF (F) do
  begin
   Read (f, Result.H[i]);
   if Result.H[i].used then
     WriteLn(Info.Phone,' ', Info.FIO);
   end;
  Close (f);
end;

begin
  WriteLn('<Инициализация>');
  HashInit(H);
  WriteLn('<Ввод информации в хэш-таблицу>');
  NewInfo(H, Inform, x);
  TablToFile(H,x,'l.dat');
  H:=FileToTabl(Inform, 'l.dat');
  WriteLn('Поиск');
  InputPhone(Phone);
  if HashFind(H, Phone, Inform) then
    WriteLn('ФИО: ', Inform.FIO)
  else
    WriteLn('Указанный номер телефона не найден');
    ReadLn;
end.

Последний раз редактировалось Stilet; 21.04.2010 в 12:40.
pwdan вне форума Ответить с цитированием
Старый 21.04.2010, 11:25   #2
Anatole
Форумчанин
 
Аватар для Anatole
 
Регистрация: 07.04.2009
Сообщений: 245
По умолчанию

Цитата:
//данные из файла. Эта функция не работает!
поправте этот участок кода
Код:
i:=0;
while not EOF (F) do
begin
Read (f, Result.H[i]);
With Result.H[i]
if Result.H[i].used then 
WriteLn(Info.Phone,' ', Info.FIO);
inc(i);
end;
Всякое безобразие должно быть единообразным. Тогда это называется порядком.
Anatole вне форума Ответить с цитированием
Старый 21.04.2010, 11:58   #3
Somebody
Участник клуба
 
Регистрация: 08.10.2007
Сообщений: 1,185
По умолчанию

Раз это хеш-таблица, может
Код:
var t:TInfo;
...
HashInit(Result);
while not eof(f) do
begin
  Read(f, t);
  HashAdd(Result, t);
end;
Somebody вне форума Ответить с цитированием
Старый 21.04.2010, 12:37   #4
pwdan
 
Регистрация: 24.03.2010
Сообщений: 4
По умолчанию

Всем спасибо. теперь все работает. Функция получилась такой:
Код:
function FileToTabl(FileName: String):THashTable;
var
  f: TypFile;
  fs: THashItem;
begin
  AssignFile(f, FileName);
  Reset(f);
  while not eof(f) do
  begin
    Read(f, fs);
    with fs do
    begin
      WriteLn(Info.Phone:3,Info.FIO);
      Input(Result, Info);
    end;
  end;
  CloseFile(f);
end;
pwdan вне форума Ответить с цитированием
Старый 21.04.2010, 12:58   #5
Somebody
Участник клуба
 
Регистрация: 08.10.2007
Сообщений: 1,185
По умолчанию

HashInit не забывай только.
Somebody вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Хеш - Функции 777Aidar777 Помощь студентам 0 30.12.2009 11:36
Неправильная хеш функция.(Java) _Studentka_ Помощь студентам 0 09.12.2009 22:54
Хеш-таблица. Непонятно с решением коллизии методом перемешивания внутренними цепочками Познающий Помощь студентам 9 05.12.2009 02:48
функция gets U-S Общие вопросы C/C++ 6 14.11.2009 13:49
одна функция потока, а другая функция - член класса запускающего этот поток Дмитрий_Ч Общие вопросы C/C++ 2 27.09.2007 08:50