注意子串的開頭和末尾加不加上星號是有區別的。這個算法與用遞歸算法實現的函數在用棧上可能相似,但實際上是有一些不同的,對遞歸作了一些改進而成,可能在大多數情形下比遞歸過程要快一些,快多少難定。至少有這樣的估計:當通配符比較僅僅作為查找子串用時,如源串為“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(),但不夠明白。
多謝一些網友給我提出的一些正確的見解,使得修改有了正確的方向。