2011-09-20 164 views
3

说我有两个字符串数组,名为'arrayone'和'arraytwo' 我将如何去按字母顺序排列'arrayone'(从A到Z),同时仍与第二个数组保持关系。如果你想知道'arrayone'和'arraytwo'是什么,1有姓,2有每个人的年龄。我最终的结果是把它添加到一个财富。情景按字母排序数组?

例子:

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; 

它说,不兼容的类型:“字符”和“字符串”

+0

您的数据结构错误。你没有两个数组。你有一个单一的数组,每个元素是一个名称,值对。在继续之前,请考虑切换到正确的数据结构。 –

+0

@David,我有两个数组。我将如何将它合并到一个多维数组中,然后继续? – noob

+0

你想'记录数组'。在现代Delphi中,你可以使用'TList '。 –

回答

17

给了你关于你的数据结构的建议,并看到了随后的挣扎,我想把事情弄直,并更清楚地解释我的意思。

你原来的代码有两个基本上没有连接的数组。您可以交换一个数组中的项目,并且很容易忘记为另一个数组执行此操作。它看起来像名字/年龄对真的不应该分开。这导致下面的类型声明。

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; 

我已经一个一个地写了这个答案,这就是你应该如何处理这样一个更大的问题。尝试把它分解成更小的部分,每个部分都是可管理的。

+0

+1。一个非常好的答案。 –

+0

泡沫排序只是一场表演噩梦。但是,无论如何,我知道这里是出于教学目的,而你从一个困惑的问题中作出了明确的回答。 –

+0

@arnaud同意。 –

2

没有创建一个包含两组数据点的新的结构,你可以排序的具有基于arrayone进行检查的比较函数的索引数组。

更具体地说,最初创建一个数组indicesindices[i] = i

然后,排序indices使用比较功能

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

然后,读取arrayone[indices[0]], arrayone[indices[1]] ...给你已排序列表中,和相应的值是arraytwo[indices[0]], arraytwo[indices[1]], ...

+0

解决方案是正确的,但语法不是(对于Delphi)。仍然是+1。 –

+0

FWIW正确的语法:'if arrayone [indices [i]] arrayone [indices [j]] then result = -1其他结果:= 0;',但当然格式正确。不需要检查我是否在这里。 –

+0

@Rudy:'i

1

排序所述第一阵列正常,使用排序算法你的选择。任何入门算法教科书都会有几个。每次交换第一个数组的两个条目时,对第二个数组的相应条目进行相同的更改。

+0

这将工作,但设计(使用单独的阵列)有点片状,国际海事组织。 –

3

我们的TDynArray wrapper只是明确地处理这个功能。

您可以使用自定义排序功能对任何现有动态数组直接进行排序,或使用索引的整数数组对其进行排序。

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; 

顺便说一句,包装的Sort方法将使用优化的快速排序,这比Bubble Sort算法快得多。

这个包装中有更多的功能,例如,类似于TList的方法,如Add()或Delete(),使用外部Count变量(快速添加),序列化或使用散列快速查找。

它从Delphi 5运行到XE2,并且是开源的。