Author: Jonas Bilinkevicius
I want to check how many of the individual characters in a search string are
matching a source string. When comparing the strings, each character position
should be checked individually. Examples:
Seach string: 'ABC' / Source string: 'ABX' / Result: 2 matching positions
Seach string: 'ABC' / Source string: 'AXB' / Result: 1 matching position
Answer:
Solve 1:
Assuming the compare always starts from the beginnig of the source string, i.e.
Search string: 'ABC' and Source string: 'AXAB' returns 1:
1 function MyStrComp(strSearch, strSource: string): integer;
2 var3 LenSearch, LenSource, Len: integer;
4 LoopCounter: integer;
5 begin6 LenSearch := length(strSearch);
7 LenSource := length(strSource);
8 if LenSearch > LenSource then9 Len := LenSource
10 else11 Len := LenSearch;
12 if Len = 0 then13 Result := 0
14 else15 begin16 LoopCounter := 1;
17 repeat18 if (strSearch[LoopCounter] <> strSource[LoopCounter] then19 break;
20 Inc(LoopCounter);
21 until22 (LoopCounter > Len);
23 Result := LoopCounter - 1;
24 end;
25 end;
The above function may not be the fastest, but it should be pretty fast. If you are
going to call this compare function in a loop and the search string will not change
within the loop, find the length of the search string before getting in the loop,
then pass it to the compare function as a parameter can save a call to the length
function in the compare function.
If you know that the source string is always longer than the search string, you can
skip comparing the lengths and use the length of the search string to control your
repeat loop.
Solve 2:
From AdvanceStringCore http://www.excommunicant.co.uk. You may use this routine for
non commercial purposes providing appropriate credit is given.
26 {Concurrent matching char elements}27 28 function ConcurrentCountMatchingCharElements(const SourceChars, MaskChars: string;
29 const CSensitive: Boolean): Integer;
30 31 {Version 1.0 (September 2000 - Lachlan Fairgrieve)32 (C)2000 Excommunicant www.excommunicant.co.uk33 Returns the number of times [mask[i]] and [source[i]] characters match}34 35 var36 {initialise :37 validate strings (for length)38 Count Lengths39 normalise lengths40 Prepare Pointers (For case insensitive and standard search)41 Source Scan : For Every [Source] Char check against every [mask] char}42 NewSource, NewMask: string; {Hold normalised strings}43 SourceP, MaskP: PChar;
44 index: Integer; {Source and Mask index vars}45 ScanLength: Integer; {The number of chrs to scan}46 begin47 {Initialise}48 Result := 0;
49 if SourceChars = '' then50 exit;
51 if MaskChars = '' then52 exit;
53 ScanLength := Length(SourceChars);
54 if Length(MaskChars) < ScanLength then55 ScanLength := Length(MaskChars);
56 {prepare string pointers}57 ifnot CSensitive then58 begin59 NewSource := uppercase(SourceChars);
60 NewMask := uppercase(MaskChars);
61 SourceP := Pointer(NewSource);
62 MaskP := Pointer(NewMask);
63 end64 else65 begin66 SourceP := Pointer(SourceChars);
67 MaskP := Pointer(MaskChars);
68 end;
69 {source scan}70 for index := 1 to ScanLength do71 begin72 if MaskP^ = SourceP^ then73 inc(result);
74 inc(MaskP);
75 inc(SourceP);
76 end;
77 end;