按自然语言规则进行字符串排序

QString 新提供了一个 NaturalCompareW 函数(兼容Delphi/C++ Builder 2007+)为大家提供按自然语言规则进行比较大小,也就是所谓的自然排序。所谓的自然排序是指像字母后面跟数字的情况下,不是按照字符本身的顺序,而是按照数字的值的顺序进行排序。如:A2 A10 A1 这三个字符串,按一般的计算机内部排序算法是 A1 A10 A2,而按自然排序的话,顺序应为:A1 A2 A10。

我们先看一下这个函数的声明:

/// <summary>使用自然语言规则比较字符串</summary>
/// <param name="s1">第一个要比较的字符串</param>
/// <param name="s2">第二个要比较的字符串</param
/// <param name="AIgnoreCase">比较时是否忽略大小写</param>
/// <remarks>本比较考虑中文全角的情况,认为中文全角符号和对应的半角符号是相等的值</remarks>
function NaturalCompareW(s1, s2: PQCharW; AIgnoreCase: Boolean): Integer;

参数说明在上面的声明中已经描述的比较清楚了,我们在其中处理了全角字符的情况,在中文自然排序规则中,我们认为全角和半角对应的同一个字符。

下面是一段示例代码,对 Memo1 中用户输入 的内容进行自然语言排序,然后输出到 Memo2 中。

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
  System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    Memo2: TMemo;
    CheckBox1: TCheckBox;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

uses QString;
{$R *.dfm}

function NCmp(List: TStringList; Index1, Index2: Integer): Integer;
begin
Result := NaturalCompareW(PQCharW(List[Index1]), PQCharW(List[Index2]), false);
end;

function NCmpI(List: TStringList; Index1, Index2: Integer): Integer;
begin
Result := NaturalCompareW(PQCharW(List[Index1]), PQCharW(List[Index2]), true);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  AList: TStringList;
begin
AList := TStringList.Create;
AList.AddStrings(Memo1.Lines);
if CheckBox1.Checked then
  AList.CustomSort(NCmpI)
else
  AList.CustomSort(NCmp);
Memo2.Lines.Assign(AList);
FreeObject(AList);
end;

end.

实际运行效果如下图所示:

1、区分大小写:

NaturalCompare1

2、忽略大小写

NaturalCompare2

本演示程序下载:

百度网盘

分享到: