Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Variablen - Größte daraus finden (https://www.delphipraxis.net/90310-variablen-groesste-daraus-finden.html)

rawsoul 15. Apr 2007 00:39


Variablen - Größte daraus finden
 
Nen schönen Abend (nunja, fast schon Morgen) zusammen.

Habe zirka 20 Integer-Variablen und möchte mir daraus die 5 größten Suchen.
Ich würde es jetzt primitiverweise mit unzähligen if-Abfragen lösen, aber ich bin mir sicher, das geht eleganter ;)

Bin für jeden Tipp dankbar.

Lg und ne gute Nacht ;)

3_of_8 15. Apr 2007 00:45

Re: Variablen - Größte daraus finden
 
Pack sie in ein Array, mach ein Quicksort und nimm die letzten 5.

rawsoul 15. Apr 2007 01:44

Re: Variablen - Größte daraus finden
 
habe ich auch drüber nachgedacht, jedoch ist das problem, dass die variablennamen sehr wichtig sind (ich benötige sie später noch) und nicht verloren gehen dürfen.

Mackhack 15. Apr 2007 06:33

Re: Variablen - Größte daraus finden
 
Was meinst du denn mit verlieren? Wie willst du die denn bei einem Quicksort verlieren?

marabu 15. Apr 2007 07:39

Re: Variablen - Größte daraus finden
 
Hallo Frank,

effizientes Sortieren und Suchen ist nur mit abstrakten Datenstrukturen zu machen. Wenn du das also vorhast, dann stellt sich mir die Frage, ob die etwa 20 Integer-Variablen nicht gleich in einem Array oder einer Liste leben könnten. An die Stelle des Namens tritt dann ein Indexwert - aus IntVar1 würde IntVar[1]. Bei der Sortierung erstellst du dann nur noch ein Array mit den sortierten Indexwerten und das war es dann auch schon. Auch eine assoziative Speicherung ist denkbar, wobei der Zugriff dann weiter mit einem Namen erfolgen kann. Die kritische Frage bleibt also: Warum hast du zwanzig einzelne Integer-Variablen?

Grüße vom marabu

rawsoul 15. Apr 2007 12:19

Re: Variablen - Größte daraus finden
 
Die Variablennamen sind aber leider nicht durchnummeriert sondern haben eigene Namen wie Haus, Vogel, Baum, Tür... Jetzt muss ich später wissen, 'wie viele Häuser', 'wie viele Vögel' ich besitze. Ein Index reicht mir da leider nicht.

Nikolas 15. Apr 2007 12:31

Re: Variablen - Größte daraus finden
 
Dann kannst du doch trotzdem ein Array of integer nehmen und dir bei der Deklaration eine Liste anlegen:
Delphi-Quellcode:
list: array of integer;
{0: Haus
1: Baum
2: Vogel}
Wenn du die Variablen später benutzt, kannst du da nachschauen und bei wichtigen COdestellen noch einen Kommentar hinterlassen:
Delphi-Quellcode:
Baumhaus=list[0]+list[1]; // Häuser+Bäume
Bei sowas solltest du nicht zu stur sein. Die Namen sind zwar manchmal einfacher zu lesen, aber doch unpraktischer. Wenn du z.B. an einem Spiel arbeitest und einen Spielstand speichern willst, musst du mit deiner Version alle Variablennamen abtippen um alles zu speichern, mit einem

Delphi-Quellcode:
for i:=0 to high(list) do
 save(list[i]);
kannst du die Liste beliebig erweitern, ohne jemals beim speichern etwas manuell zu ändern.

fLaSh11 15. Apr 2007 12:35

Re: Variablen - Größte daraus finden
 
oder machs so:
Delphi-Quellcode:
type
  TDatensatz = record
    VarName: String;
    Wert: Integer;
  end;

var
  DatenArray: Array of TDatensatz
Dann sortier nach DatenArray.Wert und lies später deren VarName aus. Den zu vertauschen nicht vergessen!

Flare 15. Apr 2007 12:40

Re: Variablen - Größte daraus finden
 
Zitat:

Zitat von Nikolas
Wenn du die Variablen später benutzt, kannst du da nachschauen und bei wichtigen COdestellen noch einen Kommentar hinterlassen:
Delphi-Quellcode:
Baumhaus=list[0]+list[1]; // Häuser+Bäume

Oder du legts dir für 0, 1, 2, ... Konstanten an, dann siehst du im Source uch ohne Kommentare was genommen wird.
Delphi-Quellcode:
type
  list_haus = 0;
  list_baum = 1;
  list_zaun = 2;
  // ...

Baumhaus=list[list_haus]+list[list_baum];

Flare

Hawkeye219 15. Apr 2007 14:09

Re: Variablen - Größte daraus finden
 
Hallo,

hier eine mögliche Lösung, die auf marabus Vorschlag basiert:

Delphi-Quellcode:
type
  TCounterList = class (TStringList)
  private
    function GetCounter (const aName: string): Cardinal;
    procedure SetCounter (const aName: string; aValue: Cardinal);
  public
    function CountByIndex (aIndex: Integer): Cardinal;
    procedure SortByCount;
    property Counter [const aName: string]: Cardinal
      read GetCounter write SetCounter;
  end;

function CompareCount (List: TStringList; Index1, Index2: Integer): Integer;
begin
  with TCounterList(List) do
    Result := CountByIndex(Index2) - CountByIndex(Index1); // umgekehrte Sortierung
end;

function TCounterList.GetCounter (const aName: string): Cardinal;
begin
  Result := CountByIndex(IndexOf(aName));
end;

function TCounterList.CountByIndex (aIndex: Integer): Cardinal;
begin
  if ((aIndex >= 0) and (aIndex < Count)) then
    Result := Integer(Objects[aIndex])
  else
    Result := 0;
end;

procedure TCounterList.SetCounter (const aName: string; aValue: Cardinal);
var
  k : Integer;
begin
  k := IndexOf(aName);
  if (k < 0) then
    k := Add(aName);
  Objects[k] := TObject(aValue);
end;

procedure TCounterList.SortByCount;
begin
  CustomSort (CompareCount);
end;
Die Anwendung könnte so aussehen:

Delphi-Quellcode:
const
  FMT_Rang = 'Rang %d: %s (Anzahl=%d)';
  FMT_Haus = 'Häuser: %d';
  FMT_Tier = 'Tiere: %d';
var
  List : TCounterList;
begin
  List := TCounterList.Create;

  List.Counter['Haus'] := 200;
  List.Counter['Baum'] := 50;
  List.Counter['Auto'] := 114;
  List.Counter['Person'] := 14;
  List.Counter['Blume'] := 344;
  List.Counter['Tier'] := 9;

  List.SortByCount;

  Memo1.Clear;
  Memo1.Lines.Add(Format(FMT_Rang, [1, List[0], List.CountByIndex(0)]));
  Memo1.Lines.Add(Format(FMT_Rang, [2, List[1], List.CountByIndex(1)]));
  Memo1.Lines.Add(Format(FMT_Rang, [3, List[2], List.CountByIndex(2)]));
  Memo1.Lines.Add('');
  Memo1.Lines.Add(Format(FMT_Haus,[List.Counter['Haus']]));
  Memo1.Lines.Add(Format(FMT_Tier,[List.Counter['Tier']]));

  List.Free;
end;
Wer es ganz sauber mag, der leitet nicht von TStringList ab, sondern verwendet eine lokale Instanz der Stringliste in der TCounterList-Klasse. Damit können nur die benötigten Methoden und Eigenschaften nach außen sichtbar gemacht werden.

Gruß Hawkeye

rawsoul 15. Apr 2007 15:37

Re: Variablen - Größte daraus finden
 
Zitat:

Zitat von fLaSh11
oder machs so:
Delphi-Quellcode:
type
  TDatensatz = record
    VarName: String;
    Wert: Integer;
  end;

var
  DatenArray: Array of TDatensatz

Habe schon viel von records gelesen, mich aber nie damit beschäftigt. Scheint ne nützliche Sache zu sein... Ich Werde es einmal so versuchen und die Idee mit Konstanten von Flare austesten.
Vielen Dank schonmal für all die Tips und Ideen, ich werde Ergebnisse posten ;)


Alle Zeitangaben in WEZ +1. Es ist jetzt 14:44 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz