大悟还俗

邮箱 key_ok@qq.com 我的收集 http://pan.baidu.com/share/home?uk=1177427271
posts - 236, comments - 8, trackbacks - 0, articles - 0
  新随笔 :: 联系 :: 订阅 订阅 :: 管理

公告

KMP(字符串匹配)算法

Posted on 2013-11-18 10:35 大悟还俗 阅读(...) 评论(...) 编辑 收藏
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
    //模式数组
    arrNext : array of Integer;
    //主串数组
    Schars : array of AnsiChar;
    //字串数组
    Dchars : array of AnsiChar;

    //获取模式数组
    procedure GetNext;
    //查找匹配
    function KPM(sPos:Integer):integer;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

{ TForm1 }

procedure TForm1.GetNext;
var
  len,m,n:Integer;
begin
  m := 0;
  n := -1;
  len := Length(Dchars);
  SetLength(arrNext,len);
  arrNext[0] := -1;
  while (m+1)<= len do
  begin
    if (n = -1) or (Dchars[m] = Dchars[n]) then
    begin
      Inc(m);
      Inc(n);
      if (Dchars[m] <> Dchars[n]) then
        arrNext[m] := n
      else
        arrNext[m] := arrNext[n];
    end
    else
    begin
      n := arrNext[n];
    end;
  end;
end;

function TForm1.KPM(sPos:Integer): integer;
var
  i,j:Integer;
begin
  Result := 0;
  i := sPos;
  j := 0;
  while (i < Length(Schars)) and (j < Length(Dchars)) do
  begin
    if (Schars[i] = Dchars[j]) then
    begin
      Inc(i);
      Inc(j);
    end
    else
    begin
      Result := Result + j - arrNext[j];
      if arrNext[j] <> -1 then
      begin
        j := arrNext[j];
      end
      else
      begin
        j := 0;
        Inc(i);
      end;
    end;
  end;
  if j <> Length(Dchars) then
    Result := -1;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  s,d:string;
  index : Integer;
begin
  s := '中华人民共和国';
  d := '人民';
  index := -1;
  SetLength(Schars,Length(s));
  SetLength(Dchars,Length(d));
  Move(s[1],Schars[0],Length(s));
  Move(d[1],Dchars[0],Length(d));
  GetNext;
  index := KPM(0);
  if index = -1 then
    ShowMessage('没有找到匹配!')
  else
    ShowMessage('从第'+IntToStr(index+1)+'个字符开始匹配');
end;

end.
View Code