Delphi Array mit ausschließung von doppelten werten

koffi

Lt. Junior Grade
Registriert
Jan. 2007
Beiträge
490
hallo!

ich möchte ein array erstellen in dem alle zahlen von 0 bis 19 in zufällig gemischter reihenfolge vorkommen, leider haben meine versuche bis jetzt immer in verzweiflung geendet.

erst hab ich irgend ein komisches gerüst aus 3 schleifen gebastelt, in dem ich erst das array[0..19] erstellt hab und dann jeder position darin mit hilfe von random(19) einen wert gegeben habe. dabei habe ich irgendwie versucht mit einer if abfrage und einr weiteren schleife dublikate auszuschließen.. hat aber in einer endlosschleife geendet :freak:

dann hab ich über google folgendes entdeckt..
Result:=random(80)+1;
while Result in zahlen do
Result:=random(80)+1;
quelle

beim compilieren streicht mir das programm das "do" mit folgender begründung an:
[Fehler] Unit1.pas(72): E2015 Operator ist auf diesen Operandentyp nicht anwendbar
seltsam..
hat wer rat für mich?
 
du kannst zb noch zusätzlich 19 boolean variablem erzeugen und alle auf true stellen. wenn du eine zahl erzweugst wird sie nur gespeichert wenn der booleanwert dieser zahl true ist. wenn das zutrifft wird die zahl in deinem array gespeichert und die betroffen booleanvaribale auf false gesetzt.
falls die booleanvaribale auf false steht einfach repeaten.
 
Statt 19 Variablen würde sich halt ein Array anbieten, welches zum Aussieben zum Einsatz kommt...
 
ich packs nicht.. ich hab es mal mit nem boolean array versucht wie h3ctor es mir beschrieben hat. das ganze endet aber leider in einer endlosschleife. findet wer den fehler?

var
Form1: TForm1;
feld1: array[0..19] of Integer;
reihenfolge: array[0..19] of integer;
doppel: array[0..19] of boolean;
i, j: integer;

...

for i := 0 to 19 do
begin
while doppel = true do begin
reihenfolge := random(19)+1;
if i <> 0 then begin
for j := 0 to i-1 do begin
if reihenfolge = reihenfolge[j] then doppel := true else doppel := false;
end;
end;
end;
end;
 
Dein Problem ist vermutlich dein 0. Glied. Damit dein Programm überhaupt funktioniert musst du doppel ja mit True initialisieren. Durch if i <> 0 kommst du aber nie auf doppel = false

Und nimm für sowas code-Tags, da bleibt die Einrückung erhalten, so kann das kein Schwein lesen
 
Zuletzt bearbeitet:
ich habe deine version nicht granz verstanden, meine delphi kenntnisse sind noch nicht so weit.. aber ich hab mir da versucht was zu intepretieren und es in einen code mit meinen kenntnissen zu schreiben.
mir wird aber dieser NOT IN angestrichen, mit der begründung "operator oder semikolon fehlt"
Code:
for i := 0 to 19 do
begin
  zufallszahl := random(19);
    WHILE zufallszahl NOT IN reihenfolge do begin
    zufallszahl := random(19); //edit: diese zeile hier ist quatsch, sie müsste in einen else fall.. gibts sowas für diese art von while schleife?
    reihenfolge[i] := zufallszahl;
  end;
end;
 
Zuletzt bearbeitet:
Deswegen hatte ich es ja Pseudocode genannt. Eine Mischung aus englischer Sprache und Mathematik.

"WHILE a NOT IN b" ist somit als "solange a nicht in b ist, tue" zu lesen. NOT IN hattest du in deinem code ja schon durch die for-Schleife implementiert nur ein bisschen zu umständlich (das doppel-array hättest du dir sparen können und durch einen Wahrheitswert ersetzen können).

Und deswegen habe ich es auch gelöscht (du warst schneller), nachdem ich mir nochmal deine Version angeguckt hatte weil du ungefähr genau das implementiert hattest, was ich vorgeschlagen hatte. Also guck dir nochmal meinen bearbeiteten Post an hatte da so eine Vermutung geäußert.

Edit: Ähh und logisch wars natürlich totaler Humbug. Das NOT war zu viel.
 
Zuletzt bearbeitet:
sorry aber entweder ich versteh dich falsch oder irgendwas stimmt nicht..
mit meiner komischen schleifenverschachtelung von am anfang will ichs nicht mehr versuchen, ich hab mich ein bisschen auf diese neue art von while schleife fixiert die ich von dir gelernt hab.
ich hab das etwa so verstanden:

WHILE variable IN array do begin ... end;
so wie ich das verstanden habe wird diese schleife so oft ausgeführt wie die variable im array ist, oder?

aber er streicht mir jedes mal das do an:
[Fehler] Unit1.pas(72): E2015 Operator ist auf diesen Operandentyp nicht anwendbar
war das mit dem IN auch nur ein teil deiner pseudo sprache? ^^
 
Ja natürlich war es das. Jetzt hab ich dich aber verwirrt. :(

Code:
for i := 0 to 19 do begin
  zufallszahl_not_in_reihenfolge := False
  repeat 
    zufallszahl := random(19)+1;
    for j:= 0 to i do begin
      if zufallszahl = reihenfolge[j] do zufallszahl_not_in_reihenfolge := True;
  until zufallszahl_not_in_reihenfolge
  reihenfolge[i] := zufallszahl;
end
So ungefähr war das gemeint (ich kann kein Pascall, ich habe kein Pascall also wirst du evtl noch ein paar Syntaxfehler un uninitialisierte Variablen finden). Ist nicht unbedingt viel kürzer als deine Version, imo aber leserlicher.

Ich hoffe du verstehst jetzt wie ich das NOT IN meinte. Du könntest statt einer Variablen natürlich auch eine Funktion schreiben:

until not_in(zufallszahl, reihenfolge)

Wie du "tue solange bis" implementierst bleibt dir überlassen.
 
Zuletzt bearbeitet:
okay, weil ich nicht so lange auf eine antwort warten wollte hab ichs doch nochma ohne while..in.. versucht.
diesmal gibts keine endlosschleife, dafür haber wird das ergebnis nicht dublikatfrei, was ja eigentlich der sinn der ganzen sache sein soll..
Code:
//zuvor wurden alle doppel[0-19] auf true gesetzt.
for i := 0 to 19 do
begin

  while doppel[i] = true do
  begin

    reihenfolge[i] := random(19);


    if i = 0 then doppel[i] := false else begin   //Diese Zeile ist nur da um auszuschließen dass 
                                                                         die kommende schleife mit i = 0 läuft
          for j := i-1 downto 0 do                        //alle bereits erstellten zahlen sollen überprüft 
                                                                          werden
          begin
            if reihenfolge[i] = reihenfolge[j]
              then doppel[i] := true
              else doppel[i] := false;      //<<<<< hier ist der fehler, siehe edit2
          end;
     end;

  end;


end;

edit:
danke für deine hilfe aber ich muss dich enttäuschen.
ich habe deinen code ausprobiert und das sind einige ergebnisse:
0 0 1 6 16 9 13 5 2 8 11 8 17 6 13 3 3 14 6 2
13 9 5 8 0 7 16 18 16 14 2 13 9 14 10 18 3 12 12 17
12 18 5 3 9 5 1 18 7 5 17 13 11 11 13 9 14 12 5 9
man stellt fest: es gibt doppelte zahlen.
ein jammer..

edit2: siehe quelltext
deswegen habe ich dublikate, mein programm setzt unnötigerweise doppel auf true..
 
Zuletzt bearbeitet:
Ja habe ich auch gemerkt. Bevor ich es schrieb hatte ich noch dran gedacht, dann nicht mehr (deswegen poste ich ungern ungetesteten Code). Du musst wenn reihenfolge = reihenfolge[j] die Schleife natürlich mit Break verlassen. Das wird auch der Fehler in deinem ersten Programm gewesen sein.

Code:
//zuvor wurden alle doppel[0-19] auf true gesetzt.
for i := 0 to 19 do
begin

  while doppel[i] = true do
  begin

    reihenfolge[i] := random(19);


    if i = 0 then doppel[i] := false else begin   //Diese Zeile ist nur da um auszuschließen dass 
                                                                         die kommende schleife mit i = 0 läuft
          for j := i-1 downto 0 do                        //alle bereits erstellten zahlen sollen überprüft 
                                                                          werden
          begin
            if reihenfolge[i] = reihenfolge[j]
              then begin
                  doppel[i] := true
                  Break;
              end
              else doppel[i] := false;      //<<<<< hier ist der fehler, siehe edit2
          end;
     end;

  end;


end;
 
Zuletzt bearbeitet:
okay ich hab meine eigene version zum laufen gebracht.
der große fehler: ich dachte random(19) macht zufallszahlen von 0-19, aber es macht nur von 0-18. damit konnten meine 19 arrays ja gar nicht dublikatfrei gefüllt werden denn genau 1 dublikat musste immer drin sein!
das hier funzt:

Code:
for i := 0 to 19 do
begin

  while doppel[i] = true do
  begin
    doppel[i] := false;
    reihenfolge[i] := random(20);


    if i = 0 then doppel[i] := false else begin
          for j := i-1 downto 0 do
          begin
            if reihenfolge[i] = reihenfolge[j]
              then doppel[i] := true;
              //else doppel[i] := false;
          end;
     end;

  end;


end;

ich möchte mich rechtherzlich für deine hilfe bedanken Darii, ohne dich hätte ich das projekt wohl in den sand gesetzt ^^
Tausend Dank!
 
Und ich werd mir merken, die Sachen anders zu beschreiben ;) Ich hab zu sehr in einer anderen Sprache gedacht

Kein Pseudocode(kommt dir aber evtl trotzdem schon bekannt vor)
Code:
import random

reihenfolge = []
for i in range(20):
    zufallszahl = random.randrange(0, 20)
    while zufallszahl in reihenfolge:
        zufallszahl = random.randrange(0, 20)
    reihenfolge.append(zufallszahl)
print reihenfolge
 

Ähnliche Themen

Zurück
Oben