注意子串的开头和末尾加不加上星号是有区别的。这个算法与用递归算法实现的函数在用栈上可能相似,但实际上是有一些不同的,对递归作了一些改进而成,可能在大多数情形下比递归过程要快一些,快多少难定。至少有这样的估计:当通配符比较仅仅作为查找子串用时,如源串为“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(),但不够明白。
多谢一些网友给我提出的一些正确的见解,使得修改有了正确的方向。
新闻热点
疑难解答
图片精选