Sal*_*dor 5 delphi string delphi-7
我需要知道,如果在一个字符串中的所有字符都相等(由相同的字符组成).函数必须返回true或false,具体取决于字符串的所有元素是否等于特定的char.
我写了这个功能很好,但我正在寻找一个更优化(最快)的解决方案,字符串可以有数千个字符.
function AllElementsAreEqual(Element:Char;Str:String):Boolean;
var
i : Integer;
begin
Result:=True;
if Str<>'' then
for i:=1 to Length(Str) do
if Str[i]<>Element then
begin
Result:= False;
exit;
end;
end;
Run Code Online (Sandbox Code Playgroud)
UPDATE
最终使用了Barry Kelly Suggestion并添加了inline指令,性能得到了显着提升.
function AllElementsAreEqual(Const Element:Char;Str:String):Boolean;inline;
type
ArrayInt = Array of Integer;
var
i : Integer;
Delta: Integer;
List : ArrayInt;
Test : Integer;
begin
Result:=True;
Delta:=(Length(Str) mod 4);
if Delta<>0 then
Str:=Str+StringOfChar(Element,4-Delta);
Test:=Ord(Element) + Ord(Element) shl 8 + Ord(Element) shl 16 + Ord(Element) shl 24;
List:=ArrayInt(@(Str[1]));
for i:=0 to ((Length(Str) div 4)-1) do
if List[i]<>Test then
begin
Result:=False;
exit;
end;
end;
Run Code Online (Sandbox Code Playgroud)
更新2
对不起,但是我发布了一个旧的解决方案实现(有一个bug),现在已修复.感谢The_Fox创建了更好的Barry建议实现.
您可以考虑重复创建一个Integer值Element4次(因为这是AnsiChar在Delphi 7中),移位Ord(Element) + Ord(Element) shl 8 + Ord(Element) shl 16 + Ord(Element) shl 24,然后将字符串强制转换为a PIntegerArray(^array[0..MaxInt div 4 - 1] of Integer)并循环遍历它Length(Str) div 4,比较为整数而不是字符.您需要Length(str) mod 4手动比较最后几个字符.
你实施了巴里凯利错误的建议.当我在Delphi 7上测试它时,它甚至比你的第一次实现慢,如果你的stringlength不能被4整除,它会得到错误的结果.
我用这个字符串测试了它:StringOfChar('c', 100000) + 'x';你的新函数返回True AllElementsAreEqual('c', StringOfChar('c', 100000) + 'x'),它应该返回False.
你的实现速度较慢,因为你试图将你的字符串除以4(你失败了,但你可以自己弄清楚它失败的原因),从而创建一个需要内存分配的新字符串.
另一个危险的事情是让动态数组(整数数组)指向一个字符串.两者都被重新计算,这可能会导致奇怪的结果.请关注Barry Kelly的建议并使用PIntegerArray!
我认为Barry Kelly的意思是:
function AllElementsAreEqual(const aElement: Char; const aStr: string): Boolean;
var
lIntArray: PIntegerArray;
i: Integer;
lTest: Integer;
begin
Result := True;
lTest := Ord(aElement) + Ord(aElement) shl 8 + Ord(aElement) shl 16 + Ord(aElement) shl 24;
lIntArray := @aStr[1];
for i := 0 to Length(aStr) div 4 - 1 do
if lIntArray[i] <> lTest then
begin
Result := False;
Exit;
end;
for i := Length(aStr) - (Length(aStr) mod 4) + 1 to Length(aStr) do
if aStr[i] <> aElement then
begin
Result := False;
Exit;
end;
end;
Run Code Online (Sandbox Code Playgroud)
注意:你的函数为空字符串返回True,是吗?
NB2:请给Barry Kelly的回答而不是我的回答,因为这真的是一个超大的评论,而不是答案.