1. fast as possible
2. work on ANSI and Unicode version of Delphi
3. must be able to search both case sensitive and insensitive
4. must be able to search from a given position in a string
5. it's code must be as easier to read as possible
Of course, the first thing I did(like anyone would do) was to search the Internet using Google Almighty for a Boyer-Moore implementation(preferably in Delphi) that would meet at least half of the requirements listed above, guess what? I did not found one that would NOT give a error.
Next step: „back to the drawing board¯ -- „If you want something done right, you must do it yourself¯ or something like that.
Here's with what I came up:
function FindString(const Value, Pattern: string; const CaseSensitive: Boolean = True; const StartPos: Integer = 1): integer; var Index: Integer; jIndex: Integer; kIndex: Integer; LLenPattern: Integer; LLenValue: Integer; LSkipTable: array[Char] of Integer; LFound: Boolean; LChar: Char; function __SameChar: Boolean; begin if CaseSensitive then Result := (Value[Index] = Pattern[jIndex]) else Result := (CompareText(Value[Index], Pattern[jIndex]) = 0); end; // function __SameChar: Boolean; begin LFound := False; Result := 0; LLenPattern := Length(Pattern); if LLenPattern = 0 then begin Result := 1; LFound := True; end; // if LLenPattern = 0 then begin for LChar := Low(Char) to High(Char) do LSkipTable[LChar] := LLenPattern; if CaseSensitive then begin for kIndex := 1 to LLenPattern -1 do LSkipTable[Pattern[kIndex]] := LLenPattern -kIndex; end else begin for kIndex := 1 to LLenPattern -1 do LSkipTable[Windows.CharLower(@Pattern[kIndex])^] := LLenPattern -kIndex; end; // if CaseSensitive then begin kIndex := LLenPattern + (StartPos -1); LLenValue := Length(Value); while (NOT LFound) and (kIndex <= LLenValue) do begin Index := kIndex; jIndex := LLenPattern; while (jIndex >= 1) do begin if __SameChar then begin jIndex := jIndex -1; Index := Index -1; end else jIndex := -1; if jIndex = 0 then begin Result := Index +1; LFound := True; end; // if jIndex = 0 then begin kIndex := kIndex + LSkipTable[Value[kIndex]]; end; // while (jIndex >= 1) do begin end; // while (NOT LFound) and (kIndex <= LLenValue) do begin end;If you find any problems(or improvements) in the algorithm please let me know.