function IsAnagram(const S1, S2: String; IgnoreSpaces: Boolean = True; ExceptionOnError: Boolean = False): Boolean;
type
TFreq = array [32..127] of Int32;
const
FZero: TFreq = (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0);
var
i: SizeInt;
F1: TFreq;
Ch: Byte;
begin
Result := False;
FillChar(F1, SizeOf(F1), 0);
i:=0;
while i<Length(S1) do
begin
inc(i);
Ch:=ord(S1[i]);
case Ch of
32..64, 91..122: Inc(F1[Ch]);
65..90: Inc(F1[Ch or $20]);
else
if ExceptionOnError then Raise ERangeError.CreateFmt('IsAnagram: illegal character in S1 at position %d',[i]);
end;
end;
i:=0;
while i<Length(S2) do
begin
inc(i);
Ch:=ord(S2[i]);
case Ch of
32..64, 91..122: Dec(F1[Ch]);
65..90: Dec(F1[Ch or $20]);
else
if ExceptionOnError then Raise ERangeError.CreateFmt('IsAnagram: illegal character in S1 at position %d',[i]);
end;
end;
if IgnoreSpaces then
begin
Result := CompareMem(@F1[Low(F1)+1], @FZero, SizeOf(TFreq)-SizeOf(TFreq[Low(TFreq)]));
end else
begin
Result := CompareMem(@F1, @FZero, SizeOf(TFreq));
end;
end;