我希望有一个 Pos() 适合用于指定源字符串内的边界,而不是让它在整个数据中执行搜索。
假设我有一个 100 个字符长的字符串,我只想在 (unicode/utf8) 字符串的第 5 个和第 20 个字符之间执行 Pos。
该代码应该改编自 delphi 中的 ASM fastcode 实现,并且显然避免将字符串部分预先复制到临时字符串,因为目的是使其比这更快。
我的场景:
我有一个被访问多次的字符串,每次都会将其一部分复制到另一个临时字符串,然后对其执行 Pos 操作。我想避免每次都进行中间复制,而是在我指定的边界内执行 Pos。
编辑:新问题被视为重复后编辑的问题。
我仍然想要一个扩展当前 XE3 FastCode 程序集实现的解决方案,因为这符合我的目标。
这是一个不基于 asm 的替代方案。
它还适用于 64 位应用程序。
function PosExUBound(const SubStr, Str: UnicodeString; Offset,EndPos: Integer): Integer; overload;
var
I, LIterCnt, L, J: NativeInt;
PSubStr, PS: PWideChar;
begin
L := Length(SubStr);
if (EndPos > Length(Str)) then
EndPos := Length(Str);
{ Calculate the number of possible iterations. Not valid if Offset < 1. }
LIterCnt := EndPos - Offset - L + 1;
{- Only continue if the number of iterations is positive or zero (there is space to check) }
if (Offset > 0) and (LIterCnt >= 0) and (L > 0) then
begin
PSubStr := PWideChar(SubStr);
PS := PWideChar(Str);
Inc(PS, Offset - 1);
Dec(L);
I := 0;
J := L;
repeat
if PS[I + J] <> PSubStr[J] then
begin
Inc(I);
J := L;
Dec(LIterCnt);
if (LIterCnt < 0)
then Exit(0);
end
else
if (J > 0) then
Dec(J)
else
Exit(I + Offset);
until false;
end;
Result := 0;
end;
我将把它作为练习来实施AnsiString
重载版本。
顺便说一句,purepascal
的部分Pos()
XE3 中的函数可以说写得很差。看QC111103 purepascal 的 Pos() 循环效率低下 http://qc.embarcadero.com/wc/qcmain.aspx?d=111103。如果您愿意,请投票。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)