пошуку рядка в рядку за допомогою хеш-функції h2>
Пошук
підрядка в рядку - часто виникає на практиці завдання. Алгоритм пошуку рядка в
рядку звичайної підстановкою до кожної позиції рядка всій підрядка - метод
неефективний і взагалі сумний. Я розгляну метод пошуку за допомогою хеш-функції
- Досить простий і швидкий. P>
Кожен
символ має свій унікальний код від 0 до 255. Суть методу полягає в тому,
щоб для підрядка підрахувати деяку хеш-функцію (наприклад суму кодів всіх
символів у рядку), потім порахувати ту ж саму хеш-функцію для частини рядка,
рівною по довжині підрядку, і, в разі збігу хеш-функції, повністю
порівняти його. Прискорення роботи алгоритму пов'язано з тим, що ми кожен раз не
перераховуємо щоразу хеш-функцію, а тільки віднімаємо значення функції від
самого "старого" символу і додаємо значення функції від наступного
символу. p>
Приклад: p>
Алфавіт
кодів: p>
Q
= 1 p>
W
= 2 p>
E
= 3 p>
R
= 4 p>
T
= 5 p>
Y
= 6 p>
підрядок:
QWERTY p>
Строка:
QWERYTEWEQWERTY p>
Вважаємо
хеш-функцію для підрядка: SS = 1 +2 +3 +4 +5 +6 +7 = 28 p>
QWERYTEWEQWERTY p>
Вважаємо
хеш-функцію для перших 6 символів рядки: FS = 1 +2 +3 +4 +5 +7 +6 = 28 p>
Проводимо
повне порівняння рядків - рядки не збігаються. p>
QWERYTEWEQWERTY p>
FS
= 28 - [Q] + [E] = 28 - 1 + 3 = 30 - код не збігається, порівняння не проводимо. P>
QWERYTEWEQWERTY p>
FS
= 30 - [W] + [W] = 30 - 2 + 2 = 30 - код не збігається, порівняння не проводимо. P>
QWERYTEWEQWERTY p>
FS
= 30 - [E] + [E] = 30 - 3 + 3 = 30 - код не збігається, порівняння не проводимо. P>
QWERYTEWEQWERTY p>
FS
= 30 - [R] + [Q] = 30 - 4 + 1 = 27 - код не збігається, порівняння не проводимо. P>
QWERYTEWEQWERTY p>
FS
= 27 - [Y] + [W] = 27 - 6 + 2 = 23 - код не збігається, порівняння не проводимо. P>
QWERYTEWEQWERTY p>
FS
= 23 - [T] + [E] = 23 - 5 + 3 = 21 - код не збігається, порівняння не проводимо. P>
QWERYTEWEQWERTY p>
FS
= 21 - [E] + [R] = 21 - 3 + 4 = 22 - код не збігається, порівняння не проводимо. P>
QWERYTEWEQWERTY p>
FS
= 22 - [W] + [T] = 22 - 2 + 5 = 25 - код не збігається, порівняння не проводимо. P>
QWERYTEWEQWERTY p>
FS
= 25 - [E] + [Y] = 25 - 3 + 6 = 28 - код співпадає, повне порівняння збігається.
Ура! P>
Текст
програми: p>
Program
FSISHF; (пошуку підрядка в рядку) p>
Const p>
NStr = 30000; p>
NSub = 3000; p>
Var p>
FStr: array [1 .. NStr] of char; p>
FSub: array [1 .. NSub] of char; (substring) p>
FSum, NSum: longint; (Контрольна сума) p>
Spec, Work: word; p>
Flag: boolean; p>
Begin p>
FSum: = 0; p>
NSum: = 0; p>
FillChar (FStr, SizeOf (FStr), 0); p>
FillChar (FSub, SizeOf (FSub), 0); p>
For Spec: = 1 to NSub do p>
FSum: = FSum + Ord (FSub [Spec ]); p>
For Spec: = 1 to NSub do p>
NSum: = NSum + Ord (FStr [Spec ]); p>
For Spec: = NSub to NStr do begin p>
If NSum = FSum then begin p>
Flag: = true; p>
For Work: = 1 to NSub do p>
If FSub [Work] FStr [Spec - NSub
+ Work] then begin p>
Flag: = false; p>
break; p>
end; p>
If Flag = true then begin p>
Writeln ( 'substring starts at position:
', Spec - NSub); p>
Halt; p>
end; p>
end; p>
NSum: = NSum + Ord (FStr [Spec + 1]) - Ord (FStr [Spec - NSub + 1 ]); p>
end; p>
Writeln ( 'no such substring'); p>
end. p>
Список літератури h2>
Для
підготовки даної роботи були використані матеріали з сайту http://g6prog.narod.ru/
p>