我有一个令人头疼的小谜题,应该非常有趣。
我有一组数组
arrayX : array of real;
arrayY : array of real;
表示多个点x,y,使得(arrayX [0],arrayY [0])构成一个点。 现在,我想根据X对这些数组进行排序,并且我认为必须通过arrayX获取已排序索引的列表并将其应用于两个数组,并且我的问题出现了:
如何编写一个函数,它给出了arrayX的排序索引(升序),最好是整数数组? ArrayX可以保存重复值
答案 0 :(得分:9)
我假设您已经在代码中具有排序功能,并且我不会尝试解释如何在此排序。 RTL为此目的提供TArray.Sort<T>
。
不是对值进行排序,而是对索引进行排序。添加一个间接级别。
Indices
,其中包含索引0,1,...,N-1。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 th 点是:
X[Indices[i]], Y[Indices[i]]
此技术称为间接排序。
您提出的问题确实表明您可能没有正确定义数据结构。而不是两个不同的数组,一个包含X坐标,一个包含Y坐标,这似乎更适合存储单个点数组:
type
TPoint = record
X: Real;
Y: Real;
end;
var
Points: array of TPoint;
现在,您可以通过对Points
值进行排序,然后交换整个点来对X
进行排序。当您以这种方式表示数据时,坐标不可能混乱。 X
坐标永远不会与匹配的Y
坐标分开。
答案 1 :(得分: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;