Delphi 按字母顺序排列数组?

Delphi 按字母顺序排列数组?,delphi,delphi-7,Delphi,Delphi 7,假设我有两个字符串数组,分别名为'arrayone'和'arraytwo' 如何按字母顺序(从A到Z)对“arrayone”进行排序,同时保持与第二个数组的关系 如果你想知道“arrayone”和“arraytwo”中是什么,1有姓氏,2有每个人的年龄。我的最终结果是将其添加到richedit 场景示例: Smith 25 Appleseed 32 Gibbs 45 必须变成: Appleseed 32 Gibbs

假设我有两个字符串数组,分别名为'arrayone'和'arraytwo' 如何按字母顺序(从A到Z)对“arrayone”进行排序,同时保持与第二个数组的关系

如果你想知道“arrayone”和“arraytwo”中是什么,1有姓氏,2有每个人的年龄。我的最终结果是将其添加到richedit

场景示例:

Smith           25 
Appleseed       32
Gibbs           45
必须变成:

Appleseed       32
Gibbs           45
Smith           25
请不要使用stringlist,将其保存在简单数组和过程中

更新:我切换到录制

尝试此代码无效

for i := 0 to 26 do
for j := 0 to 26 do
  if recordname.surname[j] > recordname.surname[j+1] then begin
    line := recordname.surname[j];
    line[j] := recordname.surname[j+1];
    recordname.surname[j+1] := line;
  end;

它表示不兼容的类型:“Char”和“String”

如果不创建包含两组数据点的新结构,您可以使用比较函数对索引数组进行排序,该函数基于arrayone进行检查

更具体地说,首先创建一个数组
index
,其中
index[i]=i

然后,使用比较函数对索引进行排序

i < j iff arrayone[indices[i]] < arrayone[indices[j]]
i

然后,读取
arrayone[index[0]]、arrayone[index[1]]…
将给出已排序的列表,相应的值是
arraytwo[index[0]]、arraytwo[index[1]]、…
使用您选择的排序算法将第一个数组按常规排序。任何介绍算法的教科书都有几本。每次交换第一个数组的两个条目时,对第二个数组的相应条目进行相同的更改。

在为您提供了有关数据结构的建议并看到了接下来的困难之后,我想澄清一下,并更清楚地解释我的意思

原始代码有两个基本上未连接的数组。您可以交换一个数组中的项,但很容易忘记对另一个数组进行交换。在我看来,姓名/年龄对真的不应该分开。这将导致以下类型声明

type
  TPerson = record
    Name: string;
    Age: Integer;
  end;
现在您需要保存一个
TPerson
数组

type
  TPersonArray = array of TPerson;
为了执行排序,您需要能够比较两个项目并交换它们

function Compare(const Person1, Person2: TPerson): Integer;
begin
  Result := CompareText(Person1.Name, Person2.Name);
end;

procedure Swap(var Person1, Person2: TPerson);
var
  temp: TPerson;
begin
  temp := Person1;
  Person1 := Person2;
  Person2 := temp;
end;
现在我们可以把这一切和一个气泡排序放在一起

procedure Sort(var People: TPersonArray);
var
  i, n: Integer;
  Swapped: Boolean;
begin
  n := Length(People);
  repeat
    Swapped := False;
    for i := 1 to n-1 do begin
      if Compare(People[i-1], People[i])>0 then begin
        Swap(People[i-1], People[i]);
        Swapped := True;
      end;
    end;
    dec(n);
  until not Swapped;
end;
现在,如果您想使用更复杂的比较运算符,那么您可以简单地替换
Compare
。例如,如果您想按年龄对任何同名的人进行排序,则可以使用词典比较函数

function Compare(const Person1, Person2: TPerson): Integer;
begin
  Result := CompareText(Person1.Name, Person2.Name);
  if Result=0 then begin
    Result := Person2.Age-Person1.Age;
  end;
end;
function PersonCompare(const Person1, Person2: TPerson): Integer;
begin // sample function pasted from David's answer
  Result := CompareText(Person1.Name, Person2.Name);
  if Result=0 then 
    Result := Person2.Age-Person1.Age;
end;

type
  TPersonDynArray = array of TPerson;

function SortPersons(var Persons: TPersonDynArray);
var
  Person: TDynArray;
begin
  Person.Init(TypeInfo(TPersonDynArray),Persons);
  Person.Compare := PersonCompare;
  Person.Sort;
end;
我已经一块一块地写了这个答案,这就是你应该如何处理这样一个更大的问题。试着把它分解成更小的部分,每一部分都是可管理的。

我们只需明确地处理此功能

您可以直接就地对任何现有动态数组进行排序,也可以使用带有自定义排序函数的整数索引数组进行排序

function Compare(const Person1, Person2: TPerson): Integer;
begin
  Result := CompareText(Person1.Name, Person2.Name);
  if Result=0 then begin
    Result := Person2.Age-Person1.Age;
  end;
end;
function PersonCompare(const Person1, Person2: TPerson): Integer;
begin // sample function pasted from David's answer
  Result := CompareText(Person1.Name, Person2.Name);
  if Result=0 then 
    Result := Person2.Age-Person1.Age;
end;

type
  TPersonDynArray = array of TPerson;

function SortPersons(var Persons: TPersonDynArray);
var
  Person: TDynArray;
begin
  Person.Init(TypeInfo(TPersonDynArray),Persons);
  Person.Compare := PersonCompare;
  Person.Sort;
end;
顺便说一下,包装器的排序方法将使用优化的快速排序,这比冒泡排序算法快得多

这个包装中有更多的特性,例如像Add()或Delete()这样类似于TList的方法,使用外部计数变量(更快的添加),序列化或使用散列进行快速查找


它从Delphi 5到XE2都可以使用,并且是开源的。

您的数据结构是错误的。您没有两个数组。您只有一个数组,每个元素都是一个名称、值对。请考虑在继续之前切换到正确的数据结构。@戴维,我有两个数组。我将如何将其合并到多维数组中,然后继续?您想要
记录数组
。在现代的Delphi中,你可以使用
TList
@BlackJack,我在做泡泡运动。到目前为止还不多yet@David,好的,我如何将2个数组切换为记录数组?解决方案是正确的,但语法不是(对于Delphi)。仍然,+1.FWIW正确语法:
if-arrayone[index[i]]arrayone[index[j]],则结果:=-1,否则结果:=0,但当然格式正确。这里不需要检查i
iiff
代表“如果且仅当”,即逻辑等价。@RudyVelthuis您没有指出您使用的是哪个版本的delphi,所以我只是给出了一个高级别的描述。我没有问这个问题。实际上,所有版本的Delphi的语法都是相同的,所以确切的版本并不重要。这会起作用,但在我看来,(使用单独数组的)设计有点古怪。冒泡排序只是性能的噩梦。但不管怎样,我知道这是出于说教的目的,你从一个困惑的问题中得出了一个明确的答案。在长循环中调用CompareText比直接转换记录字符串(测试)慢大约3倍,你最好直接在循环中执行“if person[a].nameCompareStr,或者如果小写(person[a].name)<小写(person[b].name),则必须将其写入