实现编辑控件的增量搜索

实现编辑控件的增量搜索

LinZhenqun

2007-10-20

前言

       增量搜索(又叫渐进搜索)是我比较喜欢的一种搜索方式,这种一边输入一边搜索的模式常常能更快的找到关键字,特别是在关键字记得不全的时候。大部分代码编辑器都提供了增量搜索的功能,比如DelphiVS。在Delphi,我用得最多的快捷键几乎就是Ctrl+E了。

       这几天突然心血来潮,研究了一下增量搜索的原理,成果就是这篇文章,这大概不是最好的实现,不过从搜索速度和结果来看,基本已经满足要求了,这一点从大文件(比如Windows.pas)的测试可以证实。

       基本原理就是每输入一个字符就从前一个匹配的位置起搜索关键字,得到的匹配块压进一个栈中。在回退的时候从栈中弹出一个匹配块,然后定位到这个匹配块所指的位置。

       更加详细的实现请看下面的代码。

类结构设计

       在实现之前,我认为一定有更快的方法,因此必须设计一个更具扩展性的类结构,如下图所示:

       IIncreSearch定义了增量搜索的规范,任何增量搜索的类都可以实现该接口。TIncreSearch是一个默认的实现,即上面所说的用栈结构来保存匹配块的方法。注意这里的搜索类并没有与任何控件界面关联,它是一个纯粹的类。

       TIncreSearchHandler用于处理支持增量搜索的控件的一些消息,比如字符消息,搜索结束消息;同时它使用IncreSearch来实现控件的增量搜索。

       TEdtIncreSearchHandler实现了编辑类控件的增量搜索,关联的控件必须是TCustomEdit类型的。

代码

       下面是代码,代码是设计的最佳说明:

{**********************************************************}
摘要: 编辑控件增量搜索实现                              }
{                                                          }
作者: LinZhenqun                                        }
日期: 2007-10-11                                        }
邮件: [email protected]                              }
{**********************************************************}

unit IncreSearch;

(*******************************************************************************
  说明:
      1、本单元实现了一个编辑控件的增量搜索。
      2IIncreSearch指定增量搜索的规范,任何增量搜索类都应该实现该接口;
      3TIncreSearchIIncreSearch的一个默认实现,主要是用栈来保存搜索到的匹配块。
      4TInsreSearchHandler为搜索处理器的抽象类,它使用IIncreSearch来实现增量搜索,
         同时处理增量搜索的操作逻辑。
      5TEditInsreSearchHandler为编辑控件的搜索处理器,与之关联的控件必须是TCustomEdit
         类型的控件。

  用法:
      1、实例化一个处理器,比如TEditInsreSearchHandler,并在构造函数中传进将被搜索
         的控件。
      2、调用StarteSearch开始增量搜索。
      3、调用Searching确定增量搜索是否已经结束。

  扩展:
      1、增量搜索类:TIncreSearch只是一个默认的搜索实现类,这不是一个最快速的类,
         如果你知道如何更快速的实现增量搜索,请实现IIncreSearch接口,并在处理器
         的构造函数中传进这个类,比如:
         TSomeInsreSearchHandler.Create(TSomeControl, YourIncreSearch);
         处理器面对的是搜索接口,因此要特别注意其生命周期的管理。
      2、搜索处理器:TEditInsreSearchHandler只能处理TCustomEdit的编辑控件,对于一
         些不是从TCustomEdit继承的控件,则必须写另外的处理器。
         实现很简单,继承TInsreSearchHandler,并且必须覆盖GetSearchStrGetSearchStart
         SetMatchBlock三个抽象方法,提供搜索必需的信息。
         如想提供更多的扩展,可以覆盖TInsreSearchHandler其他的虚方法。

 ******************************************************************************)

interface

uses
  
Classes, Messages, Controls, Contnrs;

type
  
匹配的块 }
  
PMatchBlock = ^TMatchBlock;
  
TMatchBlock = record
    
Start: Integer;
    
Len: Integer;
  
end;

  
增量搜索接口 }
  
IIncreSearch = interface
    
['{A8037752-ED93-49F6-915C-6D8E82ADD631}']
    
(* 开始搜索 *)
    
procedure StartSearch(const SearchStr: string; Start: Integer = 0; MaxKey: Word = 80);
    
(* 结束搜索 *)
    
procedure EndSearch;
    
(* 增加一个字符 *)
    
function IncreaseChar(C: Char): PMatchBlock;
    
(* 减少一个字符 *)
    
function DecreaseChar: PMatchBlock;
    
(* 是否正在搜索 *)
    
function GetSearching: Boolean;
    
property Searching: Boolean read GetSearching;
  
end;

  
增量搜索的默认实现:利用栈来保存匹配块 }
  
TIncreSearch = class(TInterfacedObject, IIncreSearch)
  
private
    
FSearching: Boolean;
    
FKeyIndex: Integer;
    
FStart: Integer;
    
FSearchKey: string;
    
FSearchStr: string;
    
FMatchBlockList: TStack;
  
protected
    
procedure ClearMatchBlockList;
  
public
    
procedure StartSearch(const SearchStr: string; Start: Integer 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值