Find (with caution), indexof and sort of tstringlist

Source: Internet
Author: User

The Code of others has resulted in an even-present bug. After debugging for a day and reading the following, I suddenly realized.

 

Without a license, programmers are stuck. I got shot while I was lying down.

 

======================================

Http://www.cnblogs.com/monkeyking/articles/234685.html



I worked very tired a few days ago and was a bit confused when I was writing code. I didn't hesitate to see tstringlist. Find.

Tstringlist internally searches for related data. It is painful to know the code to be debugged. After countless times, you have to trace the code step by step before sending it.

The index returned by the find method is always incorrect. At that time, I was depressed and pressed the F1 key. The help document of find is displayed.

The function is described as follows:

Locates the index for a string in a sorted list and indicates whether a string with that

Value already exists in the list.

Note: Only Use Find with sorted lists. for unsorted lists, use the indexof

Method instead. I only blame myself for being lazy at the moment. If I don't understand it, I will discard the used indexof and use the new function easily. However

At the same time, I am also interested. Why can't find return data normally only after the tstringlist. sort method is used?

The old method is to directly jump to the classes file to view the source code:

Function tstringlist. Find (const S: string; var index: integer): Boolean;

Var

L, H, I, C: Integer;

Begin

Result: = False;

L: = 0;

H: = FCount-1;

While L <= H do

Begin

I: = (L + H) shr 1;

C: = CompareStrings (FList ^ [I]. FString, S );

If C <0 then L: = I + 1

Else begin

H: = I-1;

If C = 0 then

Begin

Result: = True;

If Duplicates <> dupAccept then L: = I;

End;

End;

End;

Index: = L;

End;

I was shocked. How did I feel so complicated? I thought it was a half-fold search algorithm. Haha.

The L and H variables represent low and high, respectively. (L + H) SHR 1 is the center value, which is completely equal to (L + H) Div 2. For binary,

Moving one digit to the right is equivalent to dividing 2. Comparestrings is used to compare the size of two strings:

Function tstringlist. comparestrings (const S1, S2: string): integer;

Begin

If casesensitive then

Result: = ansicomparestr (S1, S2)

Else

Result: = ansicomparetext (S1, S2 );

End;

Here, casesensitive is used to indicate whether it is case sensitive. ansicomparestr is case sensitive, while ansicomparetext

Otherwise. In addition, the help document also specifically describes that when two functions are used for judgment, lowercase characters are less than uppercase characters, such as 'A' <'A'

. Note that this is different from ASCII (if you continue, you can find that these two functions are an encapsulation of the API,

It also encapsulates two versions of Linux and Windows ).

At this time, we return to the find function itself, and we will find that only C <0 and c = 0 are in the judgment condition, that is, it can only search for ascending order.

Stringlist.

I couldn't help it. I looked at the sort method again.

Procedure TStringList. Sort;

Begin

CustomSort (StringListCompareStrings );

End;

A simple statement cannot be a single line. CustomSort is a public method that allows you to sort custom comparison rules.

The StringListCompareStrings parameter contains the UDF of the custom comparison rule:

TStringListSortCompare = function (List: TStringList; Index1, Index2: Integer): Integer;

The CustomSort code is as follows:

Procedure TStringList. CustomSort (Compare: TStringListSortCompare );

Begin

If not Sorted and (FCount> 1) then

Begin

Changing;

QuickSort (0, FCount-1, Compare );

Changed;

End;

End;

Changing and Changed are mainly used to trigger FOnChanging and FOnChanged. You can view the code for details. While

QuickSort uses the Quick Sort Algorithm and custom comparison rules for sorting, and then enters the QuickSort code:

Procedure TStringList. QuickSort (L, R: Integer; SCompare: TStringListSortCompare );

Var

I, J, P: Integer;

Begin

Repeat

I: = L;

J: = R;

P: = (L + R) shr 1;

Repeat

While SCompare (Self, I, P) <0 do Inc (I );

While SCompare (Self, J, P)> 0 do Dec (J );

If I <= J then

Begin

ExchangeItems (I, J );

If P = I then

P: = J

Else if P = J then

P: = I;

Inc (I );

Dec (J );

End;

Until I> J;

If L <J then QuickSort (L, J, SCompare );

L: = I;

Until I> = R;

End;

Haha, this paragraph is exactly


While SCompare (Self, I, P) <0 do Inc (I );

While SCompare (Self, J, P)> 0 do Dec (J );


The TStringList is arranged in ascending order. At this point, the general reason is clear.

Let's take a look at how IndexOf achieves search. At the beginning, I thought it must use the For loop to traverse every Item and encounter the same content.

It jumps out of the loop and finds that it does the same thing, but some optimizations are made in the middle. If the StringList has been sorted, it

The Find method with higher efficiency is automatically used for searching. In addition, the Result is used as the cyclic variable, which makes full use of resources.

The Code is as follows:

Function TStringList. IndexOf (const S: string): Integer;

Begin

If not Sorted then Result: = inherited IndexOf (S) else

If not Find (S, Result) then Result: =-1;

End;

The inheritance uses the IndexOf method in the parent class TStrings.

Function TStrings. IndexOf (const S: string): Integer;

Begin

For Result: = 0 to GetCount-1 do

If CompareStrings (Get (Result), S) = 0 then Exit;

Result: =-1;

End;

The Get method in this code is a pure virtual function in TStrings.

Function Get (Index: Integer): string; virtual; abstract;

How can pure virtual functions be used. Since it can be used, only one possibility is that the Get method is implemented in the subclass TStringList. Return

The following code is displayed in TStringList:

Function TStringList. Get (Index: Integer): string;

Begin

If (index <0) or (index> = fcount) then error (@ slistindexerror, index );

Result: = flist ^ [Index]. fstring;

End;

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.