程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> Delphi >> DELPHI的通配符比較(第五版)

DELPHI的通配符比較(第五版)

編輯:Delphi
      我以前以為Delphi中沒有通配符的現成函數,後來找到了MatchesMask()。以前在未找到這個函數時我曾經在處於自由狀態下尚有心情時便自已動手來作一個自定義的函數來實現這個功能。
      程序的算法較復雜,先在子串的末尾加上‘?*’,再讀取子串,查找子串中的通配符之間的字符,亦即子串中的子串,然後在源串中依次查找是否含有子串中的子串,不過實現起來還是費不少周折。這個函數實現了以下功能:
  1。可能大多數情形下比遞歸算法和MatchesMask()速度高些;
  2。實現了對星號和問號的所有情況下的正確比較;//這點也許仍需時間驗證
  3。支持中文;//星號和問號要在英文下的才有效
  4。支持大小寫敏感的選擇。

  注意子串的開頭和末尾加不加上星號是有區別的。這個算法與用遞歸算法實現的函數在用棧上可能相似,但實際上是有一些不同的,對遞歸作了一些改進而成,可能在大多數情形下比遞歸過程要快一些,快多少難定。至少有這樣的估計:當通配符比較僅僅作為查找子串用時,如源串為“1111111111”子串為“*11111112*”時,使用遞歸算法的時間復雜度是O(N*M),但我寫的這個函數這時將簡化成大約調用幾次POS()函數的時間復雜度,也許可以將Delphi中的POS()想象成"克努特--莫裡斯---普拉特(KMP)算法"下的O(N+M)。少量下與遞歸算法的速度比較不明顯。當源串為連續100個1,子串為連續99個1最後加上字符2下,通過在一個1000次的循環中測試,比遞歸算法要快幾秒,比MatchesMask()函數快了二十幾秒。我實際多次測試表明三者都有時成為最快,但是MatchesMask()似乎多些時候是比較慢,而遞歸的快慢變化較大,我寫的函數可能在速度上比較平均。只不過我寫的函數僅供參考用,出了問題我可是不任何負責的噢。
  function   isABClikeAX(const abc,ax:widestring):boolean; file://abc是源串,ax是子串
  var
  abcstart,axstart,abclength,axlength:integer;
  endpartabc,endpartax,subax:widestring;
  temp,abcwww,axwww:integer;
  begin  file://aaa
  temp:=0;
  abcstart:=1;
  axstart:=1;
  axwww:=1;
  abcwww:=1;
  abclength:=length(abc);
  axlength:=length(ax);
  isabclikeax:=true;
  while  axstart<=axlength  do//源串長度大於或等於子串時
    begin//bbb
      if  abcstart> abclength then
      begin
         if  (ax[axlength]='*') and (axlength=axstart) then   isabclikeax:=true
         else   isabclikeax:=false;//子串長過源串時
      break;
      end;
      if ax[axstart]='?' then
      begin
      inc(axstart);
      inc(abcstart);
      continue;
      end;
      if  ax[axstart]='*'  then
      begin
      inc(axstart);
      temp:=1;
      axwww:=axstart;
      abcwww:=abcstart;
      continue;
      end;
       if not((ax[axstart]='?')  or (ax[axstart]='*') )  then
      begin//ccc
      endpartax:=copy(ax,axstart,axlength-axstart+1)+'?*';
      subax:=copy(endpartax,1,min(pos('?',endpartax),pos('*',endpartax))-1);
      axstart:=axstart+min(pos('?',endpartax),pos('*',endpartax))-1;
      endpartabc:=copy(abc,abcstart,abclength-abcstart+1);
      if ((pos(subax,endpartabc)<>0) and (temp=1 )) or ((pos(subax,endpartabc)=1) and (temp=0)) then
      begin//ddd
      if temp=1  then      temp:=0;
      abcstart:=abcstart+(pos(subax,endpartabc)+length(subax)-1) ;  
      end//ddd
      else//ddd
      begin//ddd
        if (temp=0) and (axwww>1) then
        begin
        axstart:=axwww;
        abcwww:=abcwww+1;
        abcstart:=abcwww;
        temp:=1;
        continue;
        end;
      isabclikeax:=false;
      break;
      end;//ddd
      end;//ccc
    end;//bbb
    if   (result)   and  (abcstart<=abclength)  and (ax[axlength]<>'*')   then    isabclikeax:=false;//源串長過子串時
  end;//aaa
  FUNCTION IsLike(abc,ax:string):boolean; file://大小寫敏感的函數
  begin
  islike:=isABClikeAX(abc,ax);
  end;
  FUNCTION WideCard(abc,ax:string):boolean; file://大小寫不敏感的函數
  begin
  abc:=uppercase(abc);
  ax:=uppercase(ax);
  widecard:=isABClikeAX(abc,ax);
  end;

  
  注意USES MATH,因為用到MIN(),也可以用IF語句來代替MIN(),但不夠明白。

  多謝一些網友給我提出的一些正確的見解,使得修改有了正確的方向。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved