首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> Delphi

使用泛型 TArray 在動態陣列中搜尋與排序完整指南

     編輯:Delphi

前言

在 Delphi 開發中,動態陣列是常用的資料結構。配合 Generics.Collections 單元中的 TArray 靜態類別,我們能以泛型方式高效處理各類型陣列的搜尋、排序等操作,程式碼更簡潔且型別安全。本文將透過完整範例示範如何使用 TArray.BinarySearch 進行二分搜尋,以及 TArray.Sort 進行排序。

核心概念

  • 泛型:允許在定義演算法時不指定具體資料型別,使用時再代入實際型別(如 string、Integer)。
  • TArray:位於 System.Generics.Collections,提供 Sort、BinarySearch、IndexOf 等靜態方法,支援任意泛型陣列。
  • 前提條件:BinarySearch 要求陣列已排序,否則結果不可預期。

範例一:字串與整數陣列的二分搜尋

下列程式碼建立兩個動態陣列(字串與整數),分別搜尋目標值並顯索引位置。

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;  // 搜尋字串陣列
    Button2: TButton;  // 搜尋整數陣列
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

uses Generics.Collections;  // 引用泛型集合單元

{ 從字串動態陣列中查找指定元素 }
procedure TForm1.Button1Click(Sender: TObject);
var
  arr: array of string;
  idx: Integer;
begin
  { 建立並填入已排序資料 }
  SetLength(arr, 5);
  arr[0] := 'aaa';
  arr[1] := 'bbb';
  arr[2] := 'ccc';
  arr[3] := 'ddd';
  arr[4] := 'eee';

  { 二分搜尋:回傳找到的索引,若未找到則回傳 Length(arr) }
  TArray.BinarySearch<string>(arr, 'ddd', idx);

  { 判斷是否找到 }
  if idx < Length(arr) then
    ShowMessage('找到索引:' + IntToStr(idx))  // 顯示 3
  else
    ShowMessage('未找到');
end;

{ 從整數動態陣列中查找指定元素 }
procedure TForm1.Button2Click(Sender: TObject);
var
  arr: array of Integer;
  idx: Integer;
begin
  SetLength(arr, 5);
  arr[0] := 11;
  arr[1] := 22;
  arr[2] := 33;
  arr[3] := 44;
  arr[4] := 55;

  TArray.BinarySearch<Integer>(arr, 44, idx);

  if idx < Length(arr) then
    ShowMessage('找到索引:' + IntToStr(idx))  // 顯示 3
  else
    ShowMessage('未找到');
end;

end.

關鍵點解析

  1. SetLength(arr, 5):動態配置陣列長度。
  2. TArray.BinarySearch<T>(arr, value, idx):泛型方法,idx 為 var 參數,回傳找到的索引或插入點。
  3. 搜尋前必須確認陣列已依升序排列,否則結果錯誤。

範例二:字串與整數陣列的排序

排序是搜尋的前置作業。TArray.Sort 使用快速排序演算法,平均複雜度 O(n log n)。

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    Button1: TButton;  // 排序字串陣列
    Button2: TButton;  // 排序整數陣列
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

uses Generics.Collections;

{ 給字串動態陣列排序 }
procedure TForm1.Button1Click(Sender: TObject);
var
  arr: array of string;
  i: Integer;
begin
  { 依 Memo 行數配置陣列 }
  SetLength(arr, Memo1.Lines.Count);

  { 複製資料 }
  for i := 0 to Memo1.Lines.Count - 1 do
    arr[i] := Memo1.Lines[i];

  { 排序 }
  TArray.Sort<string>(arr);

  { 回寫顯示 }
  Memo1.Clear;
  for i := 0 to Length(arr) - 1 do
    Memo1.Lines.Add(arr[i]);
end;

{ 給整數動態陣列排序 }
procedure TForm1.Button2Click(Sender: TObject);
const
  COUNT = 10;
var
  arr: array of Integer;
  i: Integer;
begin
  SetLength(arr, COUNT);
  Randomize;
  Memo1.Clear;

  { 產生隨機數並顯示 }
  for i := 0 to COUNT - 1 do
  begin
    arr[i] := Random(100);
    Memo1.Lines.Add(IntToStr(arr[i]));
  end;

  { 排序 }
  TArray.Sort<Integer>(arr);

  { 延遲 1 秒後顯示結果 }
  Sleep(1000);
  Memo1.Clear;
  for i := 0 to COUNT - 1 do
    Memo1.Lines.Add(IntToStr(arr[i]));
end;

end.

進階用法:自訂比較器

若需降序或特定邏輯排序,可傳入 IComparer<T> 介面實作:

uses System.Generics.Defaults;

TArray.Sort<Integer>(arr, TComparer<Integer>.Construct(
  function(const Left, Right: Integer): Integer
  begin
    Result := Right - Left;  // 降序
  end));

效能與注意事項

操作時間複雜度備註
TArray.SortO(n log n)不穩定排序;大量資料建議改用 TList.Sort
TArray.BinarySearchO(log n)前提:陣列已排序
TArray.IndexOfO(n)線性搜尋,適用未排序陣列
  • 記憶體管理:動態陣列為受控型別,離開作用域自動釋放,無需手動 Finalize。
  • 型別推論:Delphi 10.4+ 支援型別推論,呼叫時可省略 <string> 等型別參數。
  • 平行處理:大型陣列排序可考慮 TTask.Run 配合 TArray.Sort 避免阻塞 UI。

總結

TArray 搭配泛型為 Delphi 動態陣列操作提供了強大、型別安全的標準庫支援。掌握 Sort 與 BinarySearch 兩大核心方法,即能應對絕大多數陣列搜尋排序需求。實務上記得:先排序、再二分搜尋,並善用自訂比較器滿足業務邏輯。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved