我需要知道字符串中的所有字符是否相等(由相同的字符组成)。该函数必须返回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;
更新
最后使用Barry Kelly建议并添加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;
更新2
我很抱歉,但我发布了一个旧的解决方案实施(带有一个错误),现在已修复。 感谢The_Fox更好地实施了Barry建议。
答案 0 :(得分:9)
您可以考虑创建一个Integer
值,Element
重复4次(因为这是Delphi 7中的AnsiChar
),转移为Ord(Element) + Ord(Element) shl 8 + Ord(Element) shl 16 + Ord(Element) shl 24
,然后对字符串进行类型转换到PIntegerArray
(^array[0..MaxInt div 4 - 1] of Integer
)并循环Length(Str) div 4
次,比较为整数而不是字符。您需要手动比较最后几个Length(str) mod 4
个字符。
答案 1 :(得分:6)
你实施了巴里凯利错误的建议。当我在Delphi 7上测试它时,它比你的第一个实现更慢,如果你的stringlength不能被4整除,它会得到错误的结果。
我用这个字符串测试了它:StringOfChar('c', 100000) + 'x';
,你的新函数返回True AllElementsAreEqual('c', StringOfChar('c', 100000) + 'x')
,而它应该返回False。
你的实现速度较慢,因为你试图将你的字符串除以4(你失败了,但你可以自己弄清楚它失败的原因),从而创建一个需要内存分配的新字符串。 / p>
另一个危险的事情是让动态数组(整数数组)指向一个字符串。两者都被重新计算,这可能会导致奇怪的结果。请遵循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;
注意:你的函数为空字符串返回True,是吗?
NB2:请给Barry Kelly的答案而不是我的答案,因为这真的是一个超大的评论,而不是答案。
答案 2 :(得分:0)
也许使用StringOfChar生成一个目标字符串重复N次的字符串,然后进行字符串比较而不是比较char-by-char。
(不知道这实际上是否更快;测量和看到)。
答案 3 :(得分:0)
您可以实现Select algorithm以更快地找到char,这不会增加字符串为“True”的速度,但它应该使它更快一些。
答案 4 :(得分:0)
获取字符串长度,使用GetMem为字符串大小分配内存。 FillChar带有所需char的内存。然后使用CompareMem比较字符串和内存
答案 5 :(得分:-3)
根据我的代码理解
Result:= False;
“:= ”用于为变量赋值。你如何比较delphi中的2个值?