| 
| 
 | Вопрос # 684/ вопрос открыт / | 
 |  Здравствуйте, уважаемые эксперты!
 Есть текстовый файл. Нужно проиндексировать его на содержимое, чтобы м.б. затем быстро найти конкретную строку по запросу.
 
 Подскажите решение.
 
|  |   Вопрос задал: Фамилия Имя Отчество (статус: Посетитель)Вопрос отправлен: 30 июня 2007, 18:52
 Состояние вопроса: открыт, ответов: 3.
 |  Ответ #1. Отвечает эксперт: Градов Ю.М. Здравствуйте, Emfs!Посмотрите, пожалуйста, в приложение. Все легко, Вы быстро разберетесь:
 Приложение:Переключить в обычный режим type  TMember = record    name  : string[50];    eMail : string[30];    Posts : LongInt;end; var  Members: array[1..50] of TMember; var  F: file of TMember;   var  F: file of TMember;begin  AssignFile(F,'members.dat');  Rewrite(F);  try    for i:= 1 to 50 do      write (F, Members[i]);  finally    CloseFile(F);  end;end;   function ReadStrFmFile(const RecN: integer): string;var s: string;begin  AssignFile(F,'members.dat');  Reset(F);  Seek(F, RecN);  read(F, S);  Result := S;  CloseFile(F);end;  
|  | Ответ отправил: Градов Ю.М. (статус: 8-ой класс)Время отправки: 30 июня 2007, 20:21
 
 |  Ответ #2. Отвечает эксперт: Матвеев Игорь Владимирович Здравствуйте, Emfs!Прочитать все строки файла подряд, вычислить для каждой строки какой-нибудь простой хэш, вроде crc32 и сохранить в массиве вида (hash | line).
 Если файл очень большой, требуется очень быстрый поиск, а время на предподготовку довольно много - тогда отсортировать этот массив по hash.
 
 При поиске строки - вычислить хеш искомой строки, с помощью бинарного поиска найти в массиве элемент с нужным хешем (или любой другой алгоритм поиска по отсортированному массиву), потом обязательно прочитать найденную строку из файла и сравнить с искомой побайтово, поскольну возможны коллизии.
 Ответ #3. Отвечает эксперт: min@y™ Хочу добавить к предыдущим ответам мою фукнцию, как пример бинарного поиска строки S в отсортированном TListBox (см. приложение). Функция возвращает номер строки или -1, если строка не найдена. Приложение:Переключить в обычный режим function TMainForm.Search(const S: string): Integer;var begin  BeginPtr:= 0;  EndPtr:= ListBox.Count - 1;  InProcess:= True;  Screen.Cursor:= crHourGlass;  Application.ProcessMessages;   try    repeat      Result:= (BeginPtr + EndPtr) div 2;      if ListBox.Items[Result] = S         else begin               if CompareStr(S, ListBox.Items[Result]) < 0                 then EndPtr:= Result - 1                 else BeginPtr:= Result + 1;             end;     until EndPtr < BeginPtr;     if EndPtr < BeginPtr      then Result:= -1;  finally    Screen.Cursor:= crDefault;    InProcess:= False;  end;end;
|  | Ответ отправил: min@y™ (статус: Доктор наук)Время отправки: 2 июля 2007, 08:21
 
 |  
 Мини-форум вопросаМини-форум пуст. Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте. |