1

使用されている Delphi のバージョン: 2007

こんにちは、

私はTecordの配列を持っています

TInfo = Record
 Name : String;
 Price : Integer;
end;

var Infos : Array of Tinfo;

配列をソートする方法を探していたところInfos、賢い方法だと思われるものを見つけました。基本的に、配列の各セルへのポインターを追加する TList があります。次に、カスタムの並べ替え関数を使用してそれらを並べ替えます。次に、この TList を使用して、並べ替えられたセルを にTListView設定OwnerDataして表示しtrueます。

var SortedInfo : TList;

...

function CompareInfo(Item1, Item2: Integer): Integer;
var
 i, j : integer;
begin
 i := Integer(Item1);
 j := Integer(Item2);
 Result := CompareText(Infos[i].Name, Infos[j].Name);
end;

...

for I := 0 to Length(Infos) - 1 do SortedInfo.Add(Pointer(I));
SortedInfo.Sort(@CompareInfo);

...

procedure InfoHandlerData(Sender: TObject; Item: TListItem);
begin
 Item.Caption := Infos[Integer(SortedInfo[Item.Index])].Name;
 Item.SubItems.Add(IntToStr(Infos[Integer(SortedInfo[Item.Index])].Price);
end;

ここで、ポインターを並べ替えたまま、セルを追加および削除できるようにしたいと考えています。さて、ここに私の問題があります。

  1. セルを追加するときは、呼び出してポインターのリスト全体を再ソートする必要がありますSortedInfo.Sort(@CompareInfo);
  2. セルを削除すると、TList を消去し、ポインターのリストを再構築して、再度並べ替える必要があります。

現在、私は膨大な数のセルを持っていないので、パフォーマンスの問題はありません。ただし、セルを削除するときにポインターを再構築し、配列が変更されるたびにすべてのポインターを並べ替えるのは、私には間違っているようです。私の問題がばかげているように見える場合は申し訳ありませんが、私は学ぼうとしています.

配列をソートしておく正しい方法はありますか? 新しいセルを「個別に」ソートする方法や、セルが削除されたときにポインターを有効に保つ方法がわかりません...

4

3 に答える 3

0

動的配列と TList の両方を使用するのは良くありません。どちらか一方を使用しますが、両方は使用しないでください。TList では挿入は簡単ですが、ポインターの有効期間を管理する必要があります。ヒープ割り当てを見ています。動的配列の場合、有効期間は簡単ですが、挿入と削除には少し注意が必要です。もちろん、最新の Delphi を使用している場合は、TList を使用することは簡単です。

配列の順序を維持するには、挿入ソートを使用します。新しい項目を挿入するときは常に、前の要素よりも大きく、後続の要素よりも小さい位置に挿入します。リストがすでに順序付けされている場合、このルールに従って挿入すると、順序付けられたプロパティが維持されます。効率を上げるために、バイナリ検索を使用して挿入ポイントを見つけることができます。この例として、Sorted が True の場合の TStringList を見てください。

二分探索 (正しく理解するのは驚くほど難しい) に取り組む前に、線形探索のあるバージョンを実装してください。これが機能することを自分自身で証明し、さらに効率が必要な場合は二分探索に進みます。

削除する場合は、アイテムを削除するだけです。順序付けられた配列から項目を削除すると、順序付けられたプロパティが保持されます。

あなたの比較機能は少し「奇妙」です。あなたに必要なのは:

function CompareInfo(Item1, Item2: Integer): Integer;
begin
  Result := CompareText(Infos[Item1].Name, Infos[Item2].Name);
end;
于 2013-04-30T19:35:08.030 に答える
0

順序付けられた名前のリストとそのデータを維持したい場合は、TList の代わりに TStringList を使用します。オブジェクト属性を使用して、レコード参照を保持します。

アイテムの挿入または削除に関係なく、並べ替えが行われます。例えば:

Var
   List:TStringList;
begin
   List:=TStringList.Create();
   List.Sorted:=True;
   // depending on your duplicates records use one of the following:
   List.Duplicates:=[dupIgnore, dupAccept, dupError];

   // You add record to the list this way:
   List.AddObject(RecPtr^.name, TObject(RecPtr));
   // or
   List.AddObject(MyRecord.name, TObject(@MyRecord));
   // When you want to access the record from an item, typecast it
   with TMyRecordType(List.Objects[IndexToTheObject])^ do
   begin
   end;

   // To delete an item:
   List.Delete(Index);

   // To find a specific record:
   Index:=List.IndexOf(MyNameSearch);
end;
于 2013-05-01T12:40:52.133 に答える