How to determine if all characters in a string are equal

advertisements

I need to know if all characters in a string are equal (formed by the same character). the function must return true or false depending if all the elements of the string are equal to an particular char.

I wrote this function that works well, but I'm looking for a more optimal (fastest) solution, the strings can have thousands of chars.

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;

UPDATE finally using the Barry Kelly Suggestion and adding the inline directive, the performance was significantly improved.

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;

UPDATE 2

i'm sorry but i posted an old implementation of the solution (with a bug), now is fixed. Thanks to The_Fox for create a better implementation of the Barry suggestion.


You could consider creating an Integer value with the Element repeated 4 times (since this is AnsiChar in Delphi 7), shifted like Ord(Element) + Ord(Element) shl 8 + Ord(Element) shl 16 + Ord(Element) shl 24, then typecast the string to a PIntegerArray (^array[0..MaxInt div 4 - 1] of Integer) and loop over it Length(Str) div 4 times, comparing as integers instead of characters. You'll need to compare the last few Length(str) mod 4 characters manually though.