Entwickler-Ecke

Grafische Benutzeroberflächen (VCL & FireMonkey) - StringGrid mit negativen Werten sortieren


Do0mJump3R - Mi 06.10.10 18:38
Titel: StringGrid mit negativen Werten sortieren
Hallo zusammen,

hab folgendes problem:

möchte ein StringGrid so sortieren, dass es mit dem kleinsten (negativen) Wert beginnt.
Bin schon soweit gekommen, dass ich die SG nach der 2. Spalte sortiert habe, jedoch sind pos. als auch neg. Werte durcheinander.

Siehe hier:
Bild1

Hat eventuell jemand einen kleinen Tipp für mich wie ich dieses Problem lösen könnte?
Habe den Sortieralgorithmus von hier: http://www.swissdelphicenter.ch/de/showcode.php?id=423

Vielen Dank schon im Vorraus!!!

Greez
Do0mJump3R

Moderiert von user profile iconNarses: Bild als Anhang hochgeladen.


Xion - Mi 06.10.10 23:59

Also warum nach dem Sortieralgorithmus das Chaos von dem Screenshot rauskommen sollte ist mir unklar.

Das sortieren über eine StringList hat natürlich den Nachteil, dass "-" > "1" ist, also kommen die negativen Zahlen alle ans Ende.

Ich empfehle dir einen BubbleSort Algorithmus über ein record mit 2 Werten.


Delphi-Quelltext
1:
2:
3:
4:
  type TSortItem=record
    Key: extended;      // << Schlüssel, nach dem sortiert werden soll (= Spalte2)
    Param: integer;     // << Der Rest (= Spalte1)
  end;


Davon ein array, dort fügst du deine Zellen ein (ohne %-Zeichen) und sortierst es z.B. mit BubbleSort.

Den Bubblesort kriegst du als Pseudocode von hier:
http://de.wikipedia.org/wiki/Bubblesort


Do0mJump3R - Do 07.10.10 01:16

Hallo Xion,

vielen Dank für deine Antwort, habe auch schon einen Teil umgesetzt, leider ohne Erfolg.
Anbei meinen bisherigen Quelltext, vllcht bin ich einfach zu doof den Fehler zu finden?!?


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
procedure TForm4.BubbleSort( A : TStringGrid );
var
 n, i: Integer;
 vertauscht: boolean;
begin
  n := A.RowCount;
  repeat
    vertauscht := false;
    for i := 1 to n - 1 do begin
      if A.Cells[ 2,i ] > A.Cells[ 2, i + 1 ] then begin
        ExchangeStringGridRows(A, i, i + 1);
        vertauscht := true;
      end;
    end;
    n := n - 1;
  until (vertauscht = True) and (n > 1);
end;

procedure TForm4.ExchangeStringGridRows(const AGrid: TStringGrid; Row1, Row2: Integer);
var
  Temp: TStrings;
begin
  Temp:=TStringList.Create;
  try
    Temp.Assign(AGrid.Rows[Row1]);
    AGrid.Rows[Row1].Assign(AGrid.Rows[Row2]);
    AGrid.Rows[Row2].Assign(Temp);
  finally
    Temp.Free;
  end;
end;


Greez Do0mJump3R


bummi - Do 07.10.10 09:12

davon ausgehend daß in Deiner Spalte nur Zahlen sind, sollte das hier funtionieren, ansonten mußt Du anpassen und "Nicht Zahlen" gesondert behandeln, Beispiel QuickSort2

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
procedure QuickSort(AGrid: TStringGrid;Spalte:Integer);

  procedure QSort(LoIndex, HiIndex: Integer);
  var
    Lo, Hi: Integer;
    Pivot: Double;
    Swap: TStringList;
    f1,f2:Double;
  begin
    Swap := TStringList.Create;
    try
    // Wähle stets das mittlere Element als Pivotelement.
    if TryStrToFloat(AGrid.Cells[ Spalte,(LoIndex + HiIndex) div 2 ],Pivot) then
        begin
              // Stelle die Ordnung bzgl. des Pivotelements her.
              Lo := LoIndex;
              Hi := HiIndex;
              repeat
                while TryStrToFloat(AGrid.Cells[ Spalte,lo],f1) and (f1 < Pivot) do Inc(Lo);
                while TryStrToFloat(AGrid.Cells[ Spalte,hi],f2) and (f2 > Pivot) do Dec(Hi);
                if Lo <= Hi then
                begin
                  Swap.Assign (AGrid.Rows[lo]);
                  AGrid.Rows[lo].Assign(AGrid.Rows[hi]);
                  AGrid.Rows[hi].Assign(Swap);
                  Inc(Lo);
                  Dec(Hi);
                end;
              until Lo > Hi;
              // Gegebenenfalls linke Teilliste sortieren.
              if LoIndex < Hi then QSort(LoIndex, Hi);
              // Gegebenenfalls rechte Teilliste sortieren.
              if Lo < HiIndex then QSort(Lo, HiIndex);
        end;
    finally
      Swap.Free;
    end;
  end;
begin
  QSort(0, AGrid.RowCount - 1);
end;




procedure QuickSort2(AGrid: TStringGrid;Spalte:Integer);

  Function GetFloatCompare(const s:String;var F:Double):Boolean;
    begin
       if not TryStrToFloat(s,f) then f := - MaxInt;
       Result := true;
    end;
  procedure QSort(LoIndex, HiIndex: Integer);
  var
    Lo, Hi: Integer;
    Pivot: Double;
    Swap: TStringList;
    f1,f2:Double;
  begin
    Swap := TStringList.Create;
    try
    // Wähle stets das mittlere Element als Pivotelement.

    GetFloatCompare(AGrid.Cells[ Spalte,(LoIndex + HiIndex) div 2 ],Pivot);
        begin
              // Stelle die Ordnung bzgl. des Pivotelements her.
              Lo := LoIndex;
              Hi := HiIndex;
              repeat
                while GetFloatCompare(AGrid.Cells[ Spalte,lo],f1) and (f1 < Pivot) do Inc(Lo);
                while GetFloatCompare(AGrid.Cells[ Spalte,hi],f2) and (f2 > Pivot) do Dec(Hi);
                if Lo <= Hi then
                begin
                  Swap.Assign (AGrid.Rows[lo]);
                  AGrid.Rows[lo].Assign(AGrid.Rows[hi]);
                  AGrid.Rows[hi].Assign(Swap);
                  Inc(Lo);
                  Dec(Hi);
                end;
              until Lo > Hi;
              // Gegebenenfalls linke Teilliste sortieren.
              if LoIndex < Hi then QSort(LoIndex, Hi);
              // Gegebenenfalls rechte Teilliste sortieren.
              if Lo < HiIndex then QSort(Lo, HiIndex);
        end;
    finally
      Swap.Free;
    end;
  end;
begin
  QSort(0, AGrid.RowCount - 1);
end;


Do0mJump3R - Do 07.10.10 12:34

Vielen vielen Dank bummi,

die erste Quicksort-Prozedur hat das erwünschte Ergebnis geliefert!!!

Danke euch für eure schnellen Antworten!

Greez
Do0mJump3R