2011-09-20 167 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,並且是開源的。