How to get the number of matches when searching a string (Views: 30)
Problem/Question/Abstract: 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: function MyStrComp(strSearch, strSource: string): integer; var LenSearch, LenSource, Len: integer; LoopCounter: integer; begin LenSearch := length(strSearch); LenSource := length(strSource); if LenSearch > LenSource then Len := LenSource else Len := LenSearch; if Len = 0 then Result := 0 else begin LoopCounter := 1; repeat if (strSearch[LoopCounter] <> strSource[LoopCounter] then break; Inc(LoopCounter); until (LoopCounter > Len); Result := LoopCounter - 1; end; 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 www.excommunicant.co.uk. You may use this routine for non commercial purposes providing appropriate credit is given. {Concurrent matching char elements} function ConcurrentCountMatchingCharElements(const SourceChars, MaskChars: string; const CSensitive: Boolean): Integer; {Version 1.0 (September 2000 - Lachlan Fairgrieve) (C)2000 Excommunicant www.excommunicant.co.uk Returns the number of times [mask[i]] and [source[i]] characters match} var {initialise : validate strings (for length) Count Lengths normalise lengths Prepare Pointers (For case insensitive and standard search) Source Scan : For Every [Source] Char check against every [mask] char} NewSource, NewMask: string; {Hold normalised strings} SourceP, MaskP: PChar; index: Integer; {Source and Mask index vars} ScanLength: Integer; {The number of chrs to scan} begin {Initialise} Result := 0; if SourceChars = '' then exit; if MaskChars = '' then exit; ScanLength := Length(SourceChars); if Length(MaskChars) < ScanLength then ScanLength := Length(MaskChars); {prepare string pointers} if not CSensitive then begin NewSource := uppercase(SourceChars); NewMask := uppercase(MaskChars); SourceP := Pointer(NewSource); MaskP := Pointer(NewMask); end else begin SourceP := Pointer(SourceChars); MaskP := Pointer(MaskChars); end; {source scan} for index := 1 to ScanLength do begin if MaskP^ = SourceP^ then inc(result); inc(MaskP); inc(SourceP); end; end; |