デルファイ:TStringListの者の検索、IndexOfメソッドおよびソート

キー:ソートせずに、順序に並び替え前のindexOfを探します。

 

内部TStringListには、関連するデータを見つけます。数え切れないほどの時間を無駄にした後、痛み知られるコードのデバッグのみ作られたステップの追跡によってのみステップ、

今の方法は、インデックスを返す検索常に間違っている、F1キーを押す手にその時点で押さながら、ヘルプ文書がために、私たちの目の前に展開して下さい

このような機能を説明します。
リストAでソートされた文字列のインデックスを検索し、かどうかはAの文字列であることを示し、

値がすでにリストに存在します。


注また、一部で再び強調しました:

唯一のソートされたリストを検索します。ソートされていないリストでは、代わりに、IndexOfメソッドを使用します。

 

新機能を使用して簡単に振ら慣れIndexOfメソッドの知識がなくても、時には怠惰な自分を責めます。しかし、私はまた、唯一の方法、それをTStringList.Sort使用した後に正常に戻ることができたデータを検索する理由に興味を持つようになりましたか?

 

古い方法、ソースコードを表示するために、直接クラスファイルをジャンプ:

機能TStringList.Find(のconst S:文字列; VARランキング:整数):ブール;
VaRの
L、H、I、C:整数;
開始
結果:= Falseにします。
L:= 0;
H:= FCOUNT - 1。
Lながら<= Hで行う
始める
    I:=(L + H)SHR 1。
    C:=のCompareStrings(フィールド・リスト^ [I] .FString、S)。
    Cもし<0次にL = I + 1は、
    他の開始
      Hを:= I - 1。
      C = 0は、その後場合
      開始
        結果:= Trueのを。
        もし重複<> dupAcceptその後、L:= I;
      終わり;
    終わり;
終わり;
インデックス:= L;
終わり;

または、非常に複雑に感じる慎重に理解してどのように見えるか、ショックを受けることが、本来のバイナリ検索アルゴリズムです。ああ。
L、Hと低高を表す変数、(L + H)SHR 1はバイナリのために、(L + H)DIV 2に正確に等しい中間値を計算することです、

右2で割り切れる同等の1。前記CompareStrings 2つの文字列の大きさを比較するために使用されます。

関数TStringList.CompareStrings(CONST S1、S2:文字列):整数。
開始
CASESENSITIVEが続いた場合
    結果:= AnsiCompareStr(S1、S2)
他の
    結果:= AnsiCompareText(S1、S2)。
終わり;

大文字と小文字を区別は、AnsiCompareStrは大文字と小文字を区別するかどうかをマークするために、ここで使用CASESENSITIVE、AnsiCompareText

逆に。二つの機能は、このような「A」<「A」として大文字、小文字よりも小さい場合も、ヘルプドキュメントに特別に決意を説明

これは(永遠にそれを追いかけている場合、あなたはこれらの二つの機能を見つけることができますASCIIと同じ場所ではありませんAPIへのパッケージであることに注意してください、

そして、それはLinuxとWindows)の2つのバージョンをカプセル化します。

 

この時点で、我々は唯一のC <0とC = 0は、それが唯一の昇順で検索条件を決定できることを意味していることがわかります、検索機能自体に戻ります

STRINGLISTに配置。

 

Sortメソッドを見て、その後、助けることはできません。

手順TStringList.Sort;
開始
CustomSort(StringListCompareStringsを)。
終わり;

 

単純に1行の文で、単純なことはできません。CustomSortは、ユーザーがソートする比較ルールをカスタマイズするための一般的な方法です。

StringListCompareStringsパラメータは、カスタム比較関数のルールに配置されています。

TStringListSortCompare =関数(リスト:TStringListの、index1に、インデックス2:整数):整数。

次のようにCustomSortコードは次のとおりです。

手順TStringList.CustomSort(比較:TStringListSortCompareを)。
開始
ソートされていない場合(FCOUNT> 1)を
開始し
    変更。
    クイックソート(0、FCOUNT - 1、比較)。
    かわった;
終わり;
終わり;

 

変更と主に変更FOnChangingとFOnChangedをトリガするために使用され、具体的な内容は、コードを自分で見ることができます。

クイックソートは、高速ソートアルゴリズムの比較ルールとユーザ定義のソートを使用して、クイックソートコードに話している:
手順TStringList.QuickSort(L、R&LT:整数; SCompare:TStringListSortCompare);
VAR
I、J、P:整数;
始める
REPEAT
    I:= Lと、
    J = R&LT;
    P:=(L + R&LT)SHR 1;
    REPEAT
      社を行う0 <ながらSCompare(セルフ、I、P)は(I)であり、
      一方SCompare(セルフ、J、P )> 0 12月(J)で行う;
      I <= Jが、その後のIF
      始める
        ExchangeItems(I、J)を、
        IF PはIその後、=
          P:= J
        他のIF P = Jその後、
          P:= I;
        株式会社)は(Iであり、
        12月には( J);
      END;
    I> Jまで。
    もしL <J次に、クイックソート(L、J、SCompare)。
    L:= I;
I> = Rまで。
終わり;

ハハ、それはこの期間であり、

しばらくSCompare(セルフ、I、P)<0行う株式会社(I);
一方SCompare(セルフ、J、P)> 0行う12月(J)。

これは、昇順であるようにTStringListのこと。これまでのところ、大体の理由を考え出しました。

IndexOfメソッドが検索を実現する方法を見て、私はそれが確かに各項目をループするために使用していると思わ始まりは、同じコンテンツに遭遇しました

その後、ループのうち、およびSTRINGLISTは、それをソートされている場合、それは本当にそうすることであることがわかったが、いくつかの最適化を行っている途中

自動的に結果ループ変数としての使用に加えて、見つけるために、より効率的な検索方法を使用しますが、リソースの使用が圧倒的です。

コードは以下の通りであります:

機能TStringList.IndexOf(のconst S:文字列):整数;
開始
後、ソートされていない場合結果:他に=は、IndexOfメソッド(S)を継承した
    (S、結果)その結果見つからない場合:= -1;
終わり;

前記親クラスのTStringsで使用IndexOfメソッドを継承し

機能TStrings.IndexOf(のconst S:文字列):整数;
開始
1行う- GetCountのへ= 0:結果のために
    、(、結果(取得)S)をCompareStringsがあれば、その後= 0、終了
結果:= -1;
終わり;

TStringsはの方法でコードを取得し、純粋仮想関数です。

関数のGet(インデックス:整数):文字列。バーチャル; 抽象;

注ぐことができますどのように純粋仮想関数。それができるので、一つだけ可能性は子TStringListのクラスは、Getメソッドで実装されていることでもあります。に戻ります

TStringListに、彼女は次のコードを見たとき:

機能TStringList.Get(インデックス:整数):文字列。
開始
(インデックス<0)または(インデックス> = FCOUNT)[エラー(@SListIndexError、インデックス)場合。
結果:=フィールド・リスト^ [インデックス] .FString。
終わり;

彼は、文字列の指定された行を取得するために使用しました。分析が終わりに来ました。
 

"" "" "" "" "" "" "" "" "" "" "" "" "" ""

 

バイナリ検索を見つけ、速度は生まれ変わりのすべての項目のIndexOfメソッドのデフォルトながら、最速でなければなりません。しかし、アプリケーションの前に最初のソートソート見つけるか、他のインデックスエラーを返す必要があります。

 

例としては、次のとおりです:

 

VARはlst:TStringListの。
     I:整数;
ベギン

  LST:= TStringList.Create。

  試します

    LST:= TStringList.Create。
    lst.CaseSensitive:=はtrue。
    lst.Delimiter:= ""、 "";
    lst.DelimitedText:= Edit1.Text;

    ShowMessage(IntToStr(lst.IndexOf(Edit2.Text)))。
    lst.Sort;
        lst.Find(Edit2.Text、I)であれば、その後
      ShowMessage(IntToStr(I));
  最後に

    lst.Free;
  終わり;


eidt2は、文字列010A、010A、200A、200B、905Aを以下の

おすすめ

転載: www.cnblogs.com/jijm123/p/11482138.html