2014-09-05 69 views
1

我有一個小的難題,讓我頭痛,應該是相當愉快的解決。排序一個數組,並得到在德爾福索引

我有一組陣列

arrayX : array of real; 
arrayY : array of real; 

表示的多個點的x,y,使得(arrayX [0],arrayY [0])構成的點的。 現在,我想對這些數組排序相對於X,我想方式必須是通過arrayX獲得排序索引的列表,並將其應用於這兩個數組,並在這裏我的問題出現:

如何寫一個函數,給我arrayX的排序索引(升序),最好是一個整數數組? ArrayX可容納重複值

+1

爲什麼不使用Array或RealPoint? '類型 TRealPoint =記錄 x:Double; y:Double; y:Double; 結束; aArray = TRealPoint數組;' – bummi 2014-09-05 10:46:18

+0

實際的問題已被簡化,以解釋我一直在嘗試做什麼,實際上是大量的數組,這是更大的結構的一部分,需要大量的工作來完成重寫你建議的方式 hooray遺留的代碼太多了,難以重寫 – 2014-09-05 10:53:21

回答

1

我想我已經想通了,要做到這一點: 1)做一個臨時數組是輸入 2)找到臨時數組的最低值的副本 3)存儲最小值 4)的最小值設置爲NaN臨時數組 5)重複2-5,直到臨時數組不再有數量

Function indexedSort(inputArray : array of real) : array of integer; 
var 
    i,j : integer; 
    n : integer; 
    minVal : real; 
    tempArray : TArrayOfReal; 
begin 
    n := length(inputArray); 
    setLength(result,n); 
    tempArray := copy(inputArray,0,n); 
    for i:= 0 to n-1 do begin 
    for j := 0 to n-1 do begin 
     if not(IsNan(tempArray[j])) then begin //find any non-NaN value for minimum 
     minVal := tempArray[j]; 
     break; 
     end; 
    end; 
    for j:=0 to n-1 do begin //find actual min val 
     if not(isNan(tempArray[j])) then begin 
     if tempArray[j] <= minVal then begin 
      minVal := tempArray[j]; 
      result[i] := j; 
     end; 
     end; 
    end; 
    tempArray[result[i]] := NaN; 
    end; 
end; 
+0

這不是一個好的解決方案。不僅僅是因爲排序效率低下,O(N ** 2)。它也排除了可能包含NaN的排序值。更一般地說,它只適用於招收哨兵的類型。一個單獨的布爾值數組標記值已經被處理,可以解決所有這些問題。即使如此,間接搜索更清晰。 – 2014-09-05 11:03:14

9

我假設你已經在索引在你的代碼中排序能力,而不會試圖解釋如何在這裏排序。 RTL爲此提供了TArray.Sort<T>

而不是排序值,排序索引。添加一個間接級別。

  1. 創建一個包含索引0,1,...,N-1的整數數組。
  2. 對這個整數數組進行排序。
  3. 當比較指數陣列中的兩個值L和R,而不是比較L和R時,請比較X[L]X[R]

因此,對最後一點擴大,標準比較功能時排序整數看起來是這樣的:

function Compare(L, R: Integer): Integer; 
begin 
    if L<R then 
    Result := -1 
    else if L>R then 
    Result := 1 
    else 
    Result := 0; 
end; 

而是你在這一點上適用間接:

function Compare(L, R: Integer): Integer; 
begin 
    if X[L]<X[R] then 
    Result := -1 
    else if X[L]>X[R] then 
    Result := 1 
    else 
    Result := 0; 
end; 

在這個過程結束時,你有指標告訴你點的順序。第i個點是:作爲間接排序

X[Indices[i]], Y[Indices[i]] 

這種技術是已知的。


雖然您可能尚未正確定義數據結構,但您提出的問題確實存在。而不是兩個不同的陣列,一個含有X座標,以及包含Y的一個座標,它似乎更適合於存儲點的單一陣列:

type 
    TPoint = record 
    X: Real; 
    Y: Real; 
    end; 

var 
    Points: array of TPoint; 

現在,您可以通過訂購的X值進行排序Points ,但交換全部點。以這種方式表示數據時,座標不可能混亂。並且X座標永遠無法與其匹配的座標Y分開。

+0

非常有用的答案。我會考慮到這一點 我同意這個設計是有缺陷的,而且一個記錄結構會更好地爲我服務。唉,這個結構比我在這裏要大得多,許多功能取決於當前的設計(我們不都熱愛從前僱員接管的項目?),使得重寫不可行。有時候你只是必須保持你的鼻子,並使其最好的 – 2014-09-05 11:20:11

+0

從'TPoint數組'中得到一個'真正的數組'應該沒有問題:'function arrayX(Points:TPoints):真正的數組;'不要打斷你的依賴關係,直到你重構整個源碼 – 2014-09-05 11:28:36

+0

@user我明白了,但是爲了完整性的緣故,我覺得不得不爲了間接排序而提出要點 – 2014-09-05 11:39:05