Проверка на дублетность
[ Андрей Чудин ]
Вопрос проверки записей на дублетность(совпадение) при обработке больших массивов информации очень
актуальна при ведении базы данных по книжным изданиям, а также во всех случаях, когда описывается большое
множество сущностей с примерно заданным множествои атрибутов.
Проблема проверки наличию дубликатов сталкивается со сложностью обеспечения высокой производительности
процедур поиска повторных записей, а так же с тем, что часто мелкие погрешности в двух описаниях одной сущности
не дают результата при полном сопоставлении всех их атрибутов.
Задача решается сверткой множества атрибутов описания в одно цифровое значение - расчет хэша.
В данном материале речь идет о проверке на дублетность для библиографичских описаний.
Выбирается множество атрибутов UNIMARC, на основе которых будет рассчитываться хэш.
Рекомендуется издание считать дублетным и запись на него не составлять случае
если совпадают хэш значения, вычисленные по строке, составленной из следующих выходные сведения издания:
№ п/п | Выходные сведения | Атрибут |
1 | Номер ISBN | 010a |
2 | Сведения о тираже | 0109 |
3 | Язык основного текста издания | 101a |
4 | Основное заглавие | 200a |
5 | Сведения, относящиеся к заглавию | 200e |
6 | Сведения об ответственности | 200f |
7 | Сведения об издании | 205a |
8 | Сведения о переиздании | 205b |
9 | Место издания | 210a |
10 | Имя издателя | 210c |
11 | Год издания | 210d |
12 | Сведения о серии | 225a |
13 | Фамилия автора | 700a |
14 | Инициалы | 700b |
15 | Имя, отчество | 700g |
Приведенные атрибуты объединяются в одну строку, после чего рассчитывается хэщ.
В случае совпадения хэш кода с уже существующей записью в базе данных следует
предположить наличие дубликата и предложить пользователю программы проверить повторную библиографическую запись.
Алгоритм расчета представляет собой последовательное наложение ascii-кодов строки на значение хэша с циклическим побитовым сдвигом shl.
Перед расчетом строка приводится к нижнему регистру. В расчете используются только согласные кириллицы и латиницы,
а цифры заменяются соответствующими строками (1-один, 2-два и .тд.), что повышает их вес. Подобные действия делают алгоритм
нечувствительным ко многим опечаткам, знакам препинания и различному чисту пробельных символов, что так часто только и отличают
разные записи, которые следует признать одинаковыми.
Исходный код класса расчета хэша приведен ниже.
Untitled
{
===
Класс расчета хэш-кода по строке (из множества атрибутов библиографического описания)
для реализации алгоритма проверки записей на дублетность
===
Свойства:
Методы:
Execute - рассчитывает значение хэша. Сохраняет их в свойствах HashCode64 и HashCode32
procedure Execute(const Text: string); - по заданной строке
procedure Execute(AttrValueField: TField); - по заданному полю набора данных
(с) Чудин Андрей aka Xelby, август 2002
}
unit gcBiblioHashCode;
interface
uses SysUtils, DB;
type
TgcBiblioHashCode = class{(TComponent)}
private
FText: string;
FHashCode64: int64;
FHashCode32: integer;
procedure CalculateHashCode(Value: string);
protected
public
procedure Execute(const Text: string); overload;
procedure Execute(AttrValueField: TField); overload;
published
property HashCode32: integer read FHashCode32 write FHashCode32 stored false;
property HashCode64: int64 read FHashCode64 write FHashCode64 stored false;
end;
implementation
{ TgcBiblioHashCode }
procedure TgcBiblioHashCode.Execute(const Text: string);
begin
CalculateHashCode(Text);
end;
{
собирает строку из записей переданого поля набора данных
Предусловия: НД открыт и установлен на начальнуб позицию
}
procedure TgcBiblioHashCode.Execute(AttrValueField: TField);
var
Text: string;
begin
Text := '';
while not AttrValueField.DataSet.EOF do
begin
Text := Text + AttrValueField.AsString;
AttrValueField.DataSet.Next;
end;
CalculateHashCode(Text);
end;
{
Рассчитывает 32-битный и 64-битный хэши по строке.
Учитывает только согласные кириллицы и латиницы и цифры.
Игнорирует регистр.
В значении хэша под кодировку и разрешение коллизий места не отводится
}
procedure TgcBiblioHashCode.CalculateHashCode(Value: string);
var
i: integer;
CharCode: byte;
{ возвращает код символа. гласные, пробелы и служ. символы - игнорируются }
function TranslateCharCode(CharCode: Char): byte;
var
index: integer;
const
aAllChars = 'абвгдеёжзийклмнопрстуфхцчшщэюяabcdefghijklmnopqrstuvwxyz1234567890';
aGoodChars = 'бвгджзклмнпрстфхцчшщbcdfghklmnpqrstuvwxyz1234567890';
begin
index := pos(CharCode, aGoodChars); // возможна замена на aAllChars
if index > 0 then
Result := ord(CharCode)
else
Result := 0;
end;
begin
HashCode32 := 0;
HashCode64 := 0;
Value := LowerCase(Value); // игнорируем регистр
{ цифры заменяем на строки для увеличения их веса }
Value := StringReplace(Value, '0', 'нуль', [rfReplaceAll]);
Value := StringReplace(Value, '1', 'один', [rfReplaceAll]);
Value := StringReplace(Value, '2', 'два', [rfReplaceAll]);
Value := StringReplace(Value, '3', 'три', [rfReplaceAll]);
Value := StringReplace(Value, '4', 'четыре', [rfReplaceAll]);
Value := StringReplace(Value, '5', 'пять', [rfReplaceAll]);
Value := StringReplace(Value, '6', 'шесть', [rfReplaceAll]);
Value := StringReplace(Value, '7', 'семь', [rfReplaceAll]);
Value := StringReplace(Value, '8', 'восемь', [rfReplaceAll]);
Value := StringReplace(Value, '9', 'девять', [rfReplaceAll]);
for i := 1 to length(Value) do
begin
CharCode := TranslateCharCode(Value[i]);
if CharCode = 0 then continue; // незначащие символы пропускаются
{ сдвиг и наложение кода символа на хэш }
HashCode32 := (HashCode32 shl 1) xor CharCode;
HashCode64 := (HashCode64 shl 1) xor CharCode;
end;
end;
end.
Приведенный компонент может быть по Вашему запросу преобразован в компонент ActiveX для использования в любых
средах разработки под MS Windows, в.т.ч. VisualBasic, PowerBuilder, 1C etc.
Весь материал, размещенный на сайте www.bookresearch.ru, является собственностью авторов соответствующих материалов.
Любая перепечатка и перенос материалов на другие сайты возможны только с разрешения авторов и администратора сайта.
Любой может предложить свой материал для публикации у нас. Пишите администратору сайта.
|