unit Searches;

(*-----------------------------------------------------------------------------*
| Components TSearch & TFileSearch |
| Version: 2.2 |
| Last Update: 10 June 2004 |
| Compilers: Delphi 3 - Delphi 7 |
| Author: Angus Johnson - angusj-AT-myrealbox-DOT-com |
| Copyright: © 2001 -2004 Angus Johnson |
| |
| Description: Delphi implementation of the |
| Boyer-Moore-Horspool search algorithm. |
*-----------------------------------------------------------------------------*) //10.06.: Added support for widestring searches interface uses
windows, sysutils, classes; type TBaseSearch = class(TComponent)
private
fPos : pchar;
fEnd : pchar;
fPattern : string;
fPatLen : integer;
fPatInitialized : boolean;
fCaseSensitive : boolean;
JumpShift : integer;
Shift : array[#..#] of integer;
CaseBlindTable : array[#..#] of char;
procedure InitPattern;
procedure MakeCaseBlindTable;
procedure SetCaseSensitive(CaseSens: boolean);
procedure SetPattern(const Pattern: string);
procedure SetWsPattern(const WsPattern: widestring);
function FindCaseSensitive: integer;
function FindCaseInsensitive: integer;
protected
fStart : pchar;
fDataLength : integer;
procedure ClearData;
procedure SetData(Data: pchar; DataLength: integer); virtual;
public
constructor Create(aowner: tcomponent); override;
destructor Destroy; override;
//The following Find functions return the based offset of Pattern
//else POSITION_EOF (-) if the Pattern is not found ...
function FindFirst: integer;
function FindNext: integer;
function FindFrom(StartPos: integer): integer;
//To simplify searching for widestring patterns -
//assign the WsPattern property instead of the Pattern property
property WsPattern: widestring write SetWsPattern;
property Data: pchar read fStart;
property DataSize: integer read fDataLength;
published
property CaseSensitive: boolean read fCaseSensitive write SetCaseSensitive;
property Pattern: string read fPattern write SetPattern;
end; TSearch = class(TBaseSearch)
public
//Changes visibility of base SetData() method to public ...
//Note: TSearch does NOT own the data. To avoid the overhead of
//copying it, it just gets a pointer to it.
procedure SetData(Data: pchar; DataLength: integer); override;
end; TFileSearch = class(TBaseSearch)
private
fFilename: string;
procedure SetFilename(const Filename: string);
procedure Closefile;
public
destructor Destroy; override;
published
//Assigning 'Filename' creates a memory map of the named file.
//This memory mapping will be closed when either the Filename property is
//assigned to '' or the FileSearch object is destroyed.
property Filename: string read fFilename write SetFilename;
end; procedure Register; const
POSITION_EOF = -; implementation procedure Register;
begin
RegisterComponents('Samples', [TSearch, TFileSearch]);
end; //------------------------------------------------------------------------------
// TBaseSearch methods ...
//------------------------------------------------------------------------------ procedure TBaseSearch.MakeCaseBlindTable;
var
i: char;
begin
for i:= # to # do
CaseBlindTable[i]:= ansilowercase(i)[];
end;
//------------------------------------------------------------------------------ constructor TBaseSearch.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
fStart := nil;
fPattern := '';
fPatLen := ;
MakeCaseBlindTable;
fCaseSensitive := false; //Default to case insensitive searches.
fPatInitialized := false;
end;
//------------------------------------------------------------------------------ destructor TBaseSearch.Destroy;
begin
ClearData;
inherited Destroy;
end;
//------------------------------------------------------------------------------ procedure TBaseSearch.ClearData;
begin
fStart := nil;
fPos := nil;
fEnd := nil;
fDataLength := ;
end;
//------------------------------------------------------------------------------ procedure TBaseSearch.SetPattern(const Pattern: string);
begin
if fPattern = Pattern then exit;
fPattern := Pattern;
fPatLen := length(Pattern);
fPatInitialized := false;
end;
//------------------------------------------------------------------------------ procedure TBaseSearch.SetWsPattern(const WsPattern: widestring);
begin
fPatLen := length(WsPattern)*;
fPatInitialized := false;
if fPatLen = then exit;
SetString(fPattern, pchar(pointer(WsPattern)), fPatLen);
end;
//------------------------------------------------------------------------------ procedure TBaseSearch.SetData(Data: pchar; DataLength: integer);
begin
ClearData;
if (Data = nil) or (DataLength < ) then exit;
fStart := Data;
fDataLength := DataLength;
fEnd := fStart + fDataLength;
end;
//------------------------------------------------------------------------------ procedure TBaseSearch.SetCaseSensitive(CaseSens: boolean);
begin
if fCaseSensitive = CaseSens then exit;
fCaseSensitive := CaseSens;
fPatInitialized := false;
end;
//------------------------------------------------------------------------------ procedure TBaseSearch.InitPattern;
var
j: integer;
i: char;
begin
if fPatLen = then exit;
for i := # to # do Shift[i]:= fPatLen;
if fCaseSensitive then
begin
for j := to fPatLen- do
Shift[fPattern[j]]:= fPatLen - j;
JumpShift := Shift[fPattern[fPatLen]];
Shift[fPattern[fPatLen]] := ;
end else
begin
for j := to fPatLen- do
Shift[CaseBlindTable[fPattern[j]]]:= fPatLen - j;
JumpShift := Shift[CaseBlindTable[fPattern[fPatLen]]];
Shift[CaseBlindTable[fPattern[fPatLen]]] := ;
end;
fPatInitialized := true;
end;
//------------------------------------------------------------------------------ function TBaseSearch.FindFirst: integer;
begin
fPos := fStart+fPatLen-;
result := FindNext;
end;
//------------------------------------------------------------------------------ function TBaseSearch.FindFrom(StartPos: integer): integer;
begin
if StartPos < fPatLen- then //ie: StartPos must never be less than fPatLen-
fPos := fStart+fPatLen- else
fPos := fStart+StartPos;
result := FindNext;
end;
//------------------------------------------------------------------------------ function TBaseSearch.FindNext: integer;
begin
if not fPatInitialized then InitPattern;
if (fPatLen = ) or (fPatLen >= fDataLength) or (fPos >= fEnd) then
begin
fPos := fEnd;
result := POSITION_EOF;
exit;
end;
if fCaseSensitive then
result := FindCaseSensitive else
result := FindCaseInsensitive;
end;
//------------------------------------------------------------------------------ function TBaseSearch.FindCaseSensitive: integer;
var
i: integer;
j: pchar;
begin
result:= POSITION_EOF;
while fPos < fEnd do
begin
i := Shift[fPos^]; //test last character first
if i <> then //last char does not match
inc(fPos,i)
else
begin //last char matches at least
i := ;
j := fPos - fPatLen;
while (i < fPatLen) and (fPattern[i] = (j+i)^) do inc(i);
if (i = fPatLen) then
begin
result:= fPos-fStart-fPatLen+;
inc(fPos,fPatLen);
break; //FOUND!
end
else
inc(fPos,JumpShift);
end;
end;
end;
//------------------------------------------------------------------------------ function TBaseSearch.FindCaseInsensitive: integer;
var
i: integer;
j: pchar;
begin
result:= POSITION_EOF;
while fPos < fEnd do
begin
i := Shift[CaseBlindTable[fPos^]]; //test last character first
if i <> then //last char does not match
inc(fPos,i)
else
begin //last char matches at least
i := ;
j := fPos - fPatLen;
while (i < fPatLen) and
(CaseBlindTable[fPattern[i]] = CaseBlindTable[(j+i)^]) do inc(i);
if (i = fPatLen) then
begin
result:= fPos-fStart-fPatLen+;
inc(fPos,fPatLen);
break; //FOUND!
end
else
inc(fPos,JumpShift);
end;
end;
end; //------------------------------------------------------------------------------
// TSearch methods ...
//------------------------------------------------------------------------------ procedure TSearch.SetData(Data: pchar; DataLength: integer);
begin
inherited; //changes visibility of base method from protected to public
end; //------------------------------------------------------------------------------
// TFileSearch methods ...
//------------------------------------------------------------------------------ destructor TFileSearch.Destroy;
begin
CloseFile;
inherited Destroy;
end;
//------------------------------------------------------------------------------ procedure TFileSearch.SetFilename(const Filename: string);
var
filehandle: integer;
filemappinghandle: thandle;
size, highsize: integer;
begin
if (csDesigning in ComponentState) then
begin
fFilename := Filename;
exit;
end;
CloseFile;
if (Filename = '') or not FileExists(Filename) then exit;
filehandle := sysutils.FileOpen(Filename, fmopenread or fmsharedenynone);
if filehandle = then exit; //error
size := GetFileSize(filehandle, @highsize);
if (size <= ) or (highsize <> ) then //nb: files > gig not supported
begin
CloseHandle(filehandle);
exit;
end;
filemappinghandle :=
CreateFileMapping(filehandle, nil, page_readonly, , , nil);
if GetLastError = error_already_exists then filemappinghandle := ;
if filemappinghandle <> then
SetData(MapViewOfFile(filemappinghandle,file_map_read,,,),size);
if fStart <> nil then fFilename := Filename;
CloseHandle(filemappinghandle);
CloseHandle(filehandle);
end;
//------------------------------------------------------------------------------ procedure TFileSearch.CloseFile;
begin
if (csDesigning in ComponentState) then exit;
if (fStart <> nil) then UnmapViewOfFile(fStart);
fFilename := '';
ClearData;
end;
//------------------------------------------------------------------------------ end.

TSearch & TFileSearch Version 2.2 -Boyer-Moore-Horspool search algorithm的更多相关文章

  1. Leetcode OJ : Implement strStr() [ Boyer–Moore string search algorithm ] python solution

    class Solution { public: int strStr(char *haystack, char *needle) { , skip[]; char *str = haystack, ...

  2. Moore majority vote algorithm(摩尔投票算法)

    Boyer-Moore majority vote algorithm(摩尔投票算法) 简介 Boyer-Moore majority vote algorithm(摩尔投票算法)是一种在线性时间O( ...

  3. Boyer–Moore (BM)字符串搜索算法

    在计算机科学里,Boyer-Moore字符串搜索算法是一种非常高效的字符串搜索算法.它由Bob Boyer和J Strother Moore设计于1977年.此算法仅对搜索目标字符串(关键字)进行预处 ...

  4. Boyer Moore算法(字符串匹配)

    上一篇文章,我介绍了KMP算法. 但是,它并不是效率最高的算法,实际采用并不多.各种文本编辑器的"查找"功能(Ctrl+F),大多采用Boyer-Moore算法. Boyer-Mo ...

  5. Boyer-Moore 字符串匹配算法

    字符串匹配问题的形式定义: 文本(Text)是一个长度为 n 的数组 T[1..n]: 模式(Pattern)是一个长度为 m 且 m≤n 的数组 P[1..m]: T 和 P 中的元素都属于有限的字 ...

  6. grep之字符串搜索算法Boyer-Moore由浅入深(比KMP快3-5倍)

    这篇长文历时近两天终于完成了,前两天帮网站翻译一篇文章“为什么GNU grep如此之快?”,里面提及到grep速度快的一个重要原因是使用了Boyer-Moore算法作为字符串搜索算法,兴趣之下就想了解 ...

  7. grep之字符串搜索算法Boyer-Moore由浅入深(比KMP快3-5倍)(转)

    这篇长文历时近两天终于完成了,前两天帮网站翻译一篇文章“为什么GNU grep如此之快?”,里面提及到grep速度快的一个重要原因是使用了Boyer-Moore算法作为字符串搜索算法,兴趣之下就想了解 ...

  8. KMP算法简单回顾

    前言 虽从事企业应用的设计与开发,闲暇之时,还是偶尔涉猎数学和算法的东西,本篇根据个人角度来写一点关于KMP串匹配的东西,一方面向伟人致敬,另一方面也是练练手,头脑风暴.我在自娱自乐,路过的朋友别太认 ...

  9. Erlang/Elixir精选-第5期(20200106)

    The forgotten ideas in computer science-Joe Armestrong 在2020年的第一期里面,一起回顾2018年Joe的 The forgotten idea ...

随机推荐

  1. Metro应用Json数据处理

    Windows Phone 8 或者 Windows 8 平台对JSON数据的处理方式基本是一致的,需要使用DataContractJsonSerializer类将对象的实例序列化为JSON字符串,并 ...

  2. php 高并发解决方案(用于抢购) 转载

    最近在做一个团购项目,遇到个问题,就是在抢购.秒杀.抽奖等活动时,库存数量有限,但是同时下单人数超过了库存数量,就会导致商品超售问题.那么我们怎么来解决这个问题呢,我的思路如下: sql1:查询商品库 ...

  3. leetcode 之Valid Sudoku(七)

    判断行.列.九宫格内数字是否重复. 按照行.列.九宫格进行检查即可. bool validSudoku(const vector<vector<char>>& boar ...

  4. 动手编写TCP服务器系列之一:日志文件

    前言 在几个月之前,笔者想自己实现一个性能比较良好的基于tcp的服务器.于是断断续续写了个把月,因为还需要找工,还有论文什么的.拖了这么久.现在开辟这样的一个博客,我想记录下自己的思路,也和大家分享自 ...

  5. python函数库及函数标准库

    一.系统库提供的内部函数 字符函数库: 1)str.islower() :字符串是否全部是小写 2)str.isspace() :字符串是否为空 3)help(str):查询字符串函数库 4)str. ...

  6. Java学习(final、static关键词)

    final关键词 概念:final的意思为最终,不可变.final是个修饰符,它可以用来修饰类,类的成员,以及局部变量.不能修饰构造方法. 特点: 1.final修饰的类不可以被继承,但可以继承别的类 ...

  7. 更换 ECharts 散点图图标(散点图中symbol的使用)

    更换 ECharts 散点图图标 使用symbol关键字

  8. poj1562 Oil Deposits(DFS)

    题目链接 http://poj.org/problem?id=1562 题意 输入一个m行n列的棋盘,棋盘上每个位置为'*'或者'@',求'@'的连通块有几个(连通为8连通,即上下左右,两条对角线). ...

  9. Scrollify – jQuery全屏滚动插件

    和 fullPage.js 一样,Scrollify 也是一款基于 jQuery 的全屏滚动插件.跟 fullPage.js 相比,Scrollify 更加小巧,压缩后不足 4KB.但功能上不如 fu ...

  10. [hdu3934] 凸包 旋转卡壳

    大致题意: 求多边形的最大内接三角形 旋转卡壳 模板题 #include<cstdio> #include<iostream> #include<cstring> ...