Einzelnen Beitrag anzeigen

Medium

Registriert seit: 23. Jan 2008
3.679 Beiträge
 
Delphi 2007 Enterprise
 
#10

AW: Wie kann man viele Punkte schnell vergleichen?

  Alt 16. Jun 2010, 01:18
Öhm, sortiert und nur für eine Achse ginge das doch noch VIEL einfacher! Die Fenstergrenzen müssen dafür auch nach gleicher Weise wie die Punkte sortiert sein, und du kommst mit nur einem Durchlauf aus.

Mal so ein Fetzen Pseudocode:
Delphi-Quellcode:
type
  TWindow = class;
  TEdge = class
  public
    Value: Float;
    IsLeftEdge: Boolean; // im Konstruktor zuweisen, wird noch wichtig :)
    Window: TWindow; // im Konstruktor zuweisen, quasi der Parent, also Rückbezug
  end;
  TWindow = class
  public
    Left, Right: TEdge;
    LeftPointLeft: Float;
    LeftPointRight: Float;
    RightPointLeft: Float;
    RightPointRight: Float;
  end;

var
  Windows: array of TWindow;
  Edges: array of TEdge; // referenzen auf alle Edges aus dem Windows-Array sortiert nach Value
  CurrentEdgeIndex: Integer;
begin
  for i := 0 to maxPoints do
  begin
    if Points[i].X > Edges[CurrentEdgeIndex].Value then
    begin
      if Edges[CurrentEdgeIndex].IsLeftEdge then
      begin
        Edges[CurrentEdgeIndex].Window.LeftPointLeft := Points[i-1].Value;
        Edges[CurrentEdgeIndex].Window.LeftPointRight := Points[i].Value;
      end
      else
      begin
        Edges[CurrentEdgeIndex].Window.RightPointLeft := Points[i-1].Value;
        Edges[CurrentEdgeIndex].Window.RightPointRight := Points[i].Value;
      end;
      inc(CurrentEdgeIndex);
    end;
  end;
end;
Und schwupps stehen im TWindows-Array alle Punkte, die links und rechts der X-Fenstergrenzen liegen, in O(n).

Man könnte natürlich auch die Punkte in die TEdge Instanzen werfen, und sich dieses IsLeftEdge damit sparen:
Delphi-Quellcode:
type
  TWindow = class;
  TEdge = class
  public
    Value: Float;
    LeftValue, RightValue: Float;
  end;
  TWindow = class
  public
    Left, Right: TEdge;
  end;

var
  Windows: array of TWindow;
  Edges: array of TEdge; // referenzen auf alle Edges aus dem Windows-Array sortiert nach Value
  CurrentEdgeIndex: Integer;
begin
  for i := 0 to maxPoints do
  begin
    if Points[i].X > Edges[CurrentEdgeIndex].Value then
    begin
      Edges[CurrentEdgeIndex].LeftValue := Points[i-1].Value;
      Edges[CurrentEdgeIndex].RightValue := Points[i].Value;
      inc(CurrentEdgeIndex);
    end;
  end;
end;
Das spart evtl. noch (sehr minimal) Zeit in der Schleife (ein Vergleich und ein paar Dereferenzierungen, uhu), und die Werte stehen ggf. an sinnvollerer Stelle, je nach dem wie du es nachher brauchst.
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)

Geändert von Medium (16. Jun 2010 um 01:23 Uhr)
  Mit Zitat antworten Zitat