Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Zahlen "verteilen" (https://www.delphipraxis.net/24699-zahlen-verteilen.html)

Spurius 24. Jun 2004 17:36


Zahlen "verteilen"
 
Hallo,
wie kann ich Zahlen von z.b. 1-100 zufällig in 4 verschiedene "Portionen" aufteilen?
Gruß
Spurius

MrKnogge 24. Jun 2004 17:51

Re: Zahlen "verteilen"
 
Möcghtest du 4 Zufallszahlen zwischen 1 und 100, oder 4 Zufallszahlen die zusammen 100 ergeben ?

Spurius 24. Jun 2004 17:56

Re: Zahlen "verteilen"
 
Ich habe die Zahlen von 1-100 und möchte die zufällig aufteilen.

nailor 24. Jun 2004 18:07

Re: Zahlen "verteilen"
 
du könntest eine liste machen, wo du erst alle zahlen reinschreibst und dann immer eine zufällige rausnimmst. das 25 mal. dann hast du eine portion. dann noch zwei mal und die restlichen drei portionen stehen fest.

wäre eine möglichkeit

dizzy 24. Jun 2004 18:09

Re: Zahlen "verteilen"
 
Dann lass dir 3 zufällige Zahlen (hier mal n1 bis n3) zwischen 0 und 100 erzeugen, und dann ist halt:
0 <= n1 < n2 < n3 <= 100

...also die Grenzen der Pakete zufällig erzeugen

nailor 24. Jun 2004 18:25

Re: Zahlen "verteilen"
 
ich glaub so war es nicht gemeint...

dizzy 24. Jun 2004 18:26

Re: Zahlen "verteilen"
 
[OT]...dann müsste "man" sich präziser ausdrücken ;)[/OT]

Spurius 24. Jun 2004 18:35

Re: Zahlen "verteilen"
 
Hallo,
sry wenn ich das Problem etwas "unpräzise" beschrieben hab. Die Lösung von Nailor find ich gut, nur wie kann ich die Zahlen zufällig rausnehmen? Weil die sollen danach ja nicht neu durchnummeriert werden, sondern ihre Werte behalten. Dauert das nicht zu lange? Weil wenn random z.B. die letzte Zahl nicht liefert, dauert das ja ne ganze Weile, bis die erwischt wird.

nailor 24. Jun 2004 20:25

Re: Zahlen "verteilen"
 
sieh dich nach einer einfach oder doppelt verketteten liste um. dann nimm immer ein element per zufälligem index (maximaler index --> anzahl vorhandene elemente) raus, und lass die anderen eins nachrücken (deshalb kein array sondern liste, auch wenn die eventuell langsamer beim durchsuchen ist. aber wenn man die länge speichert und nicht immer neu ermittelt, sollten sich die kompletten durchläufe auf ein minimum beschränken und die ganze sache sehr schnell sein. und bei 100 zahlen macht das eh nichts aus. da müsstest du schon tausende/millionen von zahlen haben, damit das langsam wird.

StefanDP 24. Jun 2004 20:39

Re: Zahlen "verteilen"
 
wieso so kompliziert?!
mach das genau anderst herum :!:

Pseudocode:
Code:
FOR "zahl" = 1 to 100
{
  nimm "zahl" in die Liste mit der Nummer ZUFALL(1..4) auf
}

nailor 24. Jun 2004 21:07

Re: Zahlen "verteilen"
 
dann bekommt man keine vier gleich großen gruppen, und ich bin davon ausgegangen, dass das sein soll. sonst hätte ich es auch so vorgeschlagen. muss man den fragesteller fragen, wie er es haben will.

dizzy 24. Jun 2004 23:07

Re: Zahlen "verteilen"
 
Zitat:

Zitat von nailor
muss man den fragesteller fragen, wie er es haben will.

[OT]sehe ich anders... der Fragesteller sollte besser gleich sagen was er wünscht :mrgreen:[/OT]

nailor 25. Jun 2004 07:47

Re: Zahlen "verteilen"
 
das schon. aber wenn es nicht klar ist, dann:
Zitat:

Zitat von nailor
muss man den fragesteller fragen, wie er es haben will.


Spurius 25. Jun 2004 11:17

Re: Zahlen "verteilen"
 
Hallo,
ich hab das jetzt einigermaßen hinbekommen, ich hab jetzt Code mit dem ich 8 Zahlen aus der Liste mit den Zahlen von 1-32 auswählen kann.
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var a,b,c,d,e, Zahl: integer;
    SchonEnthalten: boolean;
begin
 List := TStringList.Create;
 List2 := TStringList.Create;

 for a := 1 to 32 do begin
  List.Add(inttostr(a));
 end;

 while List2.Count < 8 do begin
  Zahl := List.IndexOf(inttostr(random(list.Count)));
  for b := 0 to List2.Count - 1 do begin
   if Zahl = strtoint(List2.Strings[b]) then
     SchonEnthalten := true else SchonEnthalten := false;
  end;
  if SchonEnthalten = false then List2.Add(IntToStr(Zahl));
 end;
 Memo1.Lines.Add(List2.Text);
end;

end.
Aber es klappt nicht alles:
1.Warum sind die Zahlen immer die gleichen?
2.Warum bekomme ich manchmal eine -1 als Zahl?
Gruß
Spurius

Spurius 25. Jun 2004 16:40

Re: Zahlen "verteilen"
 
So, ich bin weitergekommen mit diesem Code:
Delphi-Quellcode:
var
  Form1: TForm1;
  List, List2: TStringlist;
implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var a,b,Zahl: integer;
    Disc: boolean;
begin
 randomize;
 List := TStringlist.Create;
 for a := 1 to 32 do begin
  List.Add(inttostr(a));
 end;

 while memo1.Lines.Count < 8 do begin
  Zahl := random(32);
   for b := 1 to memo1.Lines.Count do begin
    if inttostr(Zahl) = Memo1.Lines[b] then
     Disc := False;
    end;
   if Disc = true then Memo1.Lines.Add(IntToStr(Zahl));
  Disc := true;
 end;
end;

end.
Bitte beantwortet mir noch eine Frage:
Wie kann ich verhindern, dass eine 0 mit angezeigt wird?
Wird bei random(32) die 0 mitverwendet oder geht das erst ab 1 los?

jfheins 25. Jun 2004 17:08

Re: Zahlen "verteilen"
 
Bei Random wird die 0 afaik mitverwendet.
Delphi-Quellcode:
Random(32)
erzeugt ganzzahlige Zufallszahlen mit einem minimum von 0 und einem maximum von 31.

Du müsstest also schreiben:
Delphi-Quellcode:
zahl := random (32);
zahl := zahl + 1;

Spurius 25. Jun 2004 17:11

Re: Zahlen "verteilen"
 
Ok, noch ne Frage: Was müsste der Code aussehen wenn ich anstatt dem Memo list2 verwenden will?

whiteshark 25. Jun 2004 17:19

Re: Zahlen "verteilen"
 
Hallo,

wenn du random(32) verwendest nimmt er zufällig die zahlen zwischen 0-31 und nicht 1-32. Wenn du zwischen 1 und 32 eine zahl willst nimm doch einfach random(32)+1, dann nimmt der Rechner die Zahlen zwischen 0 und 31 und rechnet jedesmal +1 dazu.

whiteshark

MrKnogge 25. Jun 2004 17:36

Re: Zahlen "verteilen"
 
Zitat:

Zitat von Spurius
Ok, noch ne Frage: Was müsste der Code aussehen wenn ich anstatt dem Memo list2 verwenden will?

Schau dir doch einfach mal die Datentypen an, TMemo.Lines ist vom Typ TStrings, TListBox.Items ebenfalls :wink:

Spurius 25. Jun 2004 17:55

Re: Zahlen "verteilen"
 
Wie jetzt? Ich hatte es bei der List mit IndexOf versucht, aber des hat net so ganz hingehaun. Ich mein halt, durch was muss ich z.b. das Memo1.Lines[b] ersetzen? Die Zahlen sind ja keine Objekte sondern nur Variablen.

MrKnogge 25. Jun 2004 18:09

Re: Zahlen "verteilen"
 
durch ListBox2.Items , schrieb ich doch :roll:

Spurius 25. Jun 2004 18:15

Re: Zahlen "verteilen"
 
Oh, das ist ein Missverständnis. Ich meinte eine TStringList. Ich will ja nichts visuelles.

MrKnogge 25. Jun 2004 18:17

Re: Zahlen "verteilen"
 
dann einfach NamenDeinerStringList.Add :wink:

Spurius 25. Jun 2004 18:20

Re: Zahlen "verteilen"
 
Das schon, aber Memo1.Lines.Count, wie kann ich das ersetzen?

MrKnogge 25. Jun 2004 18:30

Re: Zahlen "verteilen"
 
Also jetzt markier mal TMemo und drück F1, anschliesend schaust du dir mal die Eigenschaft Lines an.

Wie ich oben geschrieben habe, ist TMemo.Lines vom Typ TStringList.

Zitat:

Das schon, aber Memo1.Lines.Count, wie kann ich das ersetzen?
`Schau dir doch den unterschied zwischen Memo1.Lines.Add und NameDeinerStringList.Add an, und ändern ihn ebenfalls.

Nicodius 25. Jun 2004 18:30

Re: Zahlen "verteilen"
 
Delphi-Quellcode:
random(32)+1

Spurius 25. Jun 2004 19:00

Re: Zahlen "verteilen"
 
@MrKnogge
Ich hoffe du hältst meine Fragerei noch aus, aber ich bring da grad einiges durcheinander:
Das mit dem Add und Count ist klar, ist ja bei TMemo und TstringList sehr ähnlich.
Aber wie kann ich diesen Ausdruck ersetzen: Memo1.Lines[b] ?
Ich hatte IndexOf probiert, aber dann kamen einige Zahlen doppelt vor.
Vielen Dank für die bisherige Hilfe
Spurius

Spurius 25. Jun 2004 19:05

Re: Zahlen "verteilen"
 
Nachtrag:
Ich hab das jetzt so gemacht:
Delphi-Quellcode:
var
  Form1: TForm1;
  List, List2: TStringlist;
implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var a,b,Zahl: integer;
    Disc: boolean;
begin
 randomize;
 List := TStringlist.Create;
 List2 := TStringlist.Create;
 for a := 1 to 32 do begin
  List.Add(inttostr(a));
 end;

 while List2.Count < 8 do begin
  Zahl := random(32);
   for b := 1 to List2.Count do begin
    if Zahl = List2.IndexOf(IntToStr(b)) then
     Disc := False;
    end;
   if Disc = true then List2.Add(IntToStr(Zahl));
  Disc := true;

 end;
 memo1.Lines.Add(List2.Text);
end;
end.
Allerdings kommen dabei die Zahlen teilweise mehrfach vor, was mir bei der Lösung mit dem Memo nicht aufgefallen ist. Wie kann ich das umgehen?

Lantis 25. Jun 2004 19:13

Re: Zahlen "verteilen"
 
Hi Spirius,

Deine anfängliches Problem war ja, wie verteile ich 100 zahlen in 4 gleichgroße Portionen.
Hat mich irgendwie angespornt. Um keine doppelten Zahlen zu erhalten, ist mir da auch eine Lösung
eingefallen. Werde mal mein Gedankengut verschütten, auch wenn Du ja selbst schon eine Lösung hast.
Ist 'ne visuelle Darstellung mit 4 Memos (memo1 bis memo4) und ein Button
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  i,z,n:integer;
  sl:TStringList;
begin
  z:=0;
  randomize;        //besser nur 1mal im Form.Create
  sl:=TStringList.Create;
  sl.Sorted:=True;  //nötig, damit nächste Zeile funktioniert
  sl.Duplicates:=dupIgnore;  //keine doppelten Zahlen
  for i:=1 to 4 do
   TMemo(FindComponent('memo' + IntToStr(i))).Clear;
  try
  while sl.Count<100 do    //solange, bis alle 100 Zahlen mal dran waren
    for i:=1 to 4 do
    begin
      n:=sl.Count;         //aktuelle Zahlenmenge merken
      while sl.Count=n do  //solange probieren bis neue Zahl ermittelt wurde
      begin
        z:=round(random(100)+1);
        sl.Add(intToStr(z));
      end;
      TMemo(FindComponent('memo' + IntToStr(i))).Lines.Add(intToStr(z));
    end;
  finally
    sl.Free;
  end;
end;
Gruß Lantis

Spurius 25. Jun 2004 19:21

Re: Zahlen "verteilen"
 
Danke dass du dich mit dem Problem beschäftigt hast, ich würde halt gern meine Lösung verwenden, wobei ich den Fehler noch nciht gefunden habe. Also wenn du dir mal meinen Code anschauen würdest, würdest du mir einen Gefallen tun.

Nikolas 25. Jun 2004 20:44

Re: Zahlen "verteilen"
 
- wofür hast du die erste Stringlist? Die wird gefüllt , aber nicht benutzt. Ich hab mal ein paar Sachen geändert und ich hab jetzt keine doppelten Zahlen mehr:

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var {a,}b,Zahl: integer;
    Disc: boolean;
begin
disc
//List := TStringlist.Create;
List2 := TStringlist.Create;
//for a := 1 to 32 do begin List.Add(inttostr(a));

while List2.Count < 8 do
begin
Zahl := random(8); // Doppelte sind schneller zu sehen
   for b := 0 to List2.Count-1 do // !!!
   begin
        if Zahl = strtoint(List2[b]) then // !!!
        Disc := False;
   end;
if Disc = true then List2.Add(IntToStr(Zahl));
Disc := true;
end;
end;
Jetzt kannst du random(99)+1 und listcount < 100 reinschreiben und dann die Liste zerschneiden.
- warum nennst du den Boolean 'disc'?? :gruebel:

TOX

MrKnogge 25. Jun 2004 21:02

Re: Zahlen "verteilen"
 
Servus Toxman,

die 2. Schleife hast du für die Überprüfung auf doppelte, oder ?

Wenn dem so ist, nimm TStringList.IndexOf(zusuchenderstring), das sparrt eine schleife, und dürfte das ganze übersichtlicher machen.

Sollte letztendlich dann so aussehen:

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  b, Zahl: integer;
begin
  List := TStringlist.Create;

  while List2.Count < 8 do
  begin
    Zahl := random(8);
    if List.IndexOf(IntToStr(Zahl)) = -1 then
      List2.Add(IntToStr(Zahl));
  end;
end;
@Spurius
Ja ich halte sie noch aus :mrgreen:

Nikolas 25. Jun 2004 21:26

Re: Zahlen "verteilen"
 
@ MrKnogge
Ja.
Ich hab bis jetzt noch kaum mit Stringlists gearbeitet, kannte den Befehl nicht und hab deswegen die Schleife noch drin.
Deine Lösung sieht im Endeffekt sehr sauber aus. :thuimb:
Ein ganz anderer Ansatz wär ein Hier im Forum suchenunsort. Hab ich grad ausprobiert, funzt auch ganz schön.

MrKnogge 25. Jun 2004 21:32

Re: Zahlen "verteilen"
 
Mal ne ganz andere Lösung, gute Idee :thuimb:

Spurius 25. Jun 2004 21:42

Re: Zahlen "verteilen"
 
Also in die erste Stringlist wollte ich die Zahlen von 1-32 reinschreiben und in die zweite die 8 zufälligen Zahlen aus der ersten. Ich werd mir des morgen mal genauer anschauen.
Gruß
Spurius

Spurius 25. Jun 2004 21:48

Re: Zahlen "verteilen"
 
So, habs mir doch noch schnell angeschaut.
Delphi-Quellcode:
for b := 0 to List2.Count-1 do // !!! 
   begin
        if Zahl = strtoint(List2[b]) then // !!!
Daran lags denk ich. Ich versteh nicht warum man List2[b] schreiben darf. Da ist ja nichtmal ein Punkt oder sowas dazwischen.
Also nochmal vielen Dank für eure Hilfe!
Gruß
Spurius

MrKnogge 25. Jun 2004 21:53

Re: Zahlen "verteilen"
 
list2[INDEX] entspricht list2.Strings[INDEX],
ist einfach der bequemlichkeit wegen :wink:

[edit]Nein, ich habe nichts an diesem Beitrag geändert, wer etwas anderes gesehen haben will der irrt :mrgreen: [/edit]

Nikolas 25. Jun 2004 21:55

Re: Zahlen "verteilen"
 
Zitat:

Zitat von The Fine Manual
Strings stellt die vorgegebene Eigenschaft von TStringList-Objekten dar. Der Bezeichner Strings braucht beim Zugiff auf diese Eigenschaft nicht angegeben zu werden. Die beiden folgenden Code-Zeilen sind gültige Anweisungen und führen zu demselben Ergebnis:

MyStringList.Strings[0] := ‘Das ist der erste String’;
MyStringList[0] := ‘Das ist der erste String’;

Es ist also egal ob man noch ein .strings reinschreibt.

Edit: @ MrKnogge ??? :gruebel:


Alle Zeitangaben in WEZ +1. Es ist jetzt 23:54 Uhr.

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