Autor Beitrag
at4germany
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 19



BeitragVerfasst: Di 18.09.07 18:51 
Hallo,
ich habe ein Frage:
und zwar habe ich einen random wert, sagen wir mal 20. Durch random kann ich ja in dem Bereich einen Zufallswert erhalten. Aber nun möchte ich, dass ich nur einmal jeden Wert erhalte, also nicht doppelt, und am ende irgendwie eine Meldung erscheint "Ende". Entweder über ein Label oder ein neues Fenster, wie kann ich das bewerkstelligen? Gibts einen extra befehl dafür?

lg
Regan
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 2157
Erhaltene Danke: 72


Java (Eclipse), Python (Sublimetext 3)
BeitragVerfasst: Di 18.09.07 19:01 
Schau dir mal das hier an.
DasMarX
Hält's aus hier
Beiträge: 3



BeitragVerfasst: Di 18.09.07 19:31 
DAs Zauberwort heißt 'Fisher-Yates'. Such mal hier danach. Im Prinzip nimmt man sich alle Zahlen, die man zufällig aber nur einmal ziehen möchte, mischt sie durch und zieht dann eben nacheinander eine Zahl von dem gemischten Stapel.
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Di 18.09.07 19:38 
@DasMarX: Die von mir unter dem genannten Link gepostete Lösung ist für diesen Fall besonders bei m=ZuZiehendeZahlen <<< n=Mögliche Zahlen wesentlich schneller als Fisher-Yates ...

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
at4germany Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 19



BeitragVerfasst: Mi 19.09.07 14:54 
so hab jetzt mal versucht das selber zu schreiben. Nur irgendwo ist noch ein Fehler den ich nicht endecken kann. Delphi meckert immer beim array rum...

ausblenden 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:
function TForm1.VokDeutsch: string;
var s: TStringList;
begin
s:= TStringList.Create;
s.LoadFromFile('D.txt');
d:= s.Count-1;  //Zählt die länge der Datei
Label7.Caption:=inttostr(d);
  try
  result:= s.Strings[d];
  finally
  s.free;
end;
end;

function TForm1.ArZahl:integer;
var i,j: integer;
    ZFeld: array [1..i] of integer;
begin
for i:= 1 to d do
begin
  z:= random(d)+1;
  ZFeld[i]:=z;
  for j:= 1 to d do
  begin
   if z:=ZFeld[i]
   then z:=random(d);
   end;
   result:=z;
end;


lg
Wonko
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 69



BeitragVerfasst: Mi 19.09.07 16:06 
Hey,

ich glaube der Fehler liegt darin begraben, wie Du ZFeld deklarierst. Du schreibst ZFeld: array [1..i] of integer;, aber wie groß ist i? Du hast eine Zeile vorher nur gesagt, es gibt einen Integer i; aber nicht initialisiert, also keinen Wert zugewiesen!

Wenn dieser Fehler besitigt ist (evtl. mit einem dynamischen Array), wird es trotzdem nicht tun, was Du willst:
ausblenden Delphi-Quelltext
1:
2:
if z:=ZFeld[i]
then z:=random(d);

lässt nur nochmal neu ziehen, aber es kann doch sein, das der selbe Wert gezogen wird, dann ist diese Abfrage völlig nutzlos.
Wenn Dir die repeat-Schleife von user profile iconRegans Link nicht zusagt, hilft Dir vielleicht ein Post von mir weiter: www.delphi-forum.de/....php?p=445965#445965
Eine weitaus unelegantere Lösung, aber sie wurde angenommen :)

_________________
"Read the directions, even if you don't follow them.", Mary Schmich
at4germany Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 19



BeitragVerfasst: Mi 19.09.07 16:14 
Ich würde ja gerne die Lösung aus regans link nehmen, aber mein Problem ist nur ich weiss nicht wie ich das einbauen sollte^^

lg
JayEff
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2971

Windows Vista Ultimate
D7 Enterprise
BeitragVerfasst: Mi 19.09.07 17:02 
user profile iconWonko hat folgendes geschrieben:
der Fehler liegt darin begraben, wie Du ZFeld deklarierst. Du schreibst ZFeld: array [1..i] of integer;, aber wie groß ist i? Du hast eine Zeile vorher nur gesagt, es gibt einen Integer i; aber nicht initialisiert, also keinen Wert zugewiesen!

Ausserdem muss bei der Deklaration eines statischen Arrays oberer und unterer Wert eine Konstante sein.
ausblenden Delphi-Quelltext
1:
2:
const x : Integer = 10;
var arr: array[0..x] of integer;
geht also.
Wenn du ein Array variabler Größe brauchst, sollte dir ein dynamisches Array helfen:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
var arr : array of integer; //Dynamische Deklaration
begin
   SetLength(arr, 10) //Länge setzen: Arr[0] bis Arr[9] (10 Elemente)
   Arr[5] := 123; //Zuweisung genau wie beim statischen Array
end;

_________________
>+++[>+++[>++++++++<-]<-]<++++[>++++[>>>+++++++<<<-]<-]<<++
[>++[>++[>>++++<<-]<-]<-]>>>>>++++++++++++++++++.+++++++.>++.-.<<.>>--.<+++++..<+.
alzaimar
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2889
Erhaltene Danke: 13

W2000, XP
D6E, BDS2006A, DevExpress
BeitragVerfasst: Mi 19.09.07 17:15 
user profile iconBenBE hat folgendes geschrieben:
@DasMarX: Die von mir unter dem genannten Link gepostete Lösung ist für diesen Fall besonders bei m=ZuZiehendeZahlen <<< n=Mögliche Zahlen wesentlich schneller als Fisher-Yates ...

Hmm..., aber längst nicht so elegant... Die Lösung von Dir ist außerdem nicht allgemeingültig und wird bei n=m und großem m sehr lange dauern, weil ständig bereits gezogene Zufallszahlen ermittelt werden....

_________________
Na denn, dann. Bis dann, denn.
at4germany Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 19



BeitragVerfasst: Mi 19.09.07 17:27 
Ok, ich habe es jetzt geändert.
So sieht es jetzt aus:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
function TForm1.ArZahl:integer;
var j,i: integer;
    var arr : array of integer;
begin
setlength(arr, 65);
Arr[i]:= random(d);
for i:= 1 to d do
begin
  z:= random(d)+1;
  Arr[i]:=z;
  for j:= 1 to d do
  begin
   if z=Arr[i]
   then z:=random(d);
   end;
   result:=z;
end;
end;


aber es geht leider immer nich nicht. Er zeigt mir eine Zufriffsverletzung der Klasse EAccessViolation an. Un wenn ich das //Arr[i]:= random(d);\\ enferne, compiliert er zwar, aber es erscheint immer nur die selbe Vokabel..

lg
Kroko
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1284

W98 W2k WXP
Turbo D
BeitragVerfasst: Mi 19.09.07 17:41 
dynamische Arrays beginnen bei 0 , also die Schleife von 0 bis d-1!

_________________
Die F1-Taste steht nicht unter Naturschutz und darf somit regelmäßig und oft benutzt werden! oder Wer lesen kann, ist klar im Vorteil!
JayEff
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2971

Windows Vista Ultimate
D7 Enterprise
BeitragVerfasst: Mi 19.09.07 19:38 
user profile iconKroko hat folgendes geschrieben:
dynamische Arrays beginnen bei 0 , also die Schleife von 0 bis d-1!

vorrausgesetzt d=65 laut deinem Code!

_________________
>+++[>+++[>++++++++<-]<-]<++++[>++++[>>>+++++++<<<-]<-]<<++
[>++[>++[>>++++<<-]<-]<-]>>>>>++++++++++++++++++.+++++++.>++.-.<<.>>--.<+++++..<+.
Kroko
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1284

W98 W2k WXP
Turbo D
BeitragVerfasst: Do 20.09.07 05:44 
user profile iconJayEff hat folgendes geschrieben:
user profile iconKroko hat folgendes geschrieben:
dynamische Arrays beginnen bei 0 , also die Schleife von 0 bis d-1!

vorrausgesetzt d=65 laut deinem Code!

Wenn nicht, wird er es merken :wink:

_________________
Die F1-Taste steht nicht unter Naturschutz und darf somit regelmäßig und oft benutzt werden! oder Wer lesen kann, ist klar im Vorteil!
at4germany Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 19



BeitragVerfasst: Do 20.09.07 16:05 
danke, aber fehler bleibt immernoch bestehen... irgendwas stimmt nicht mit dem Arr[i]:= random(d);
auch wenn ich anstelle d 65 eintrag bekomm ich immer noch eine Meldung "zugriffsverletzung"...
Wonko
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 69



BeitragVerfasst: Do 20.09.07 16:36 
Ich versuch's nochmal: Du solltest i einen Wert zuweisen.
Zitat:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
var j,i: integer;
var arr : array of integer;
begin
setlength(arr, 65);
Arr[i]:= random(d);
...
Bisher steht da (u.a.): "es gibt einen Integer mit dem Namen i"; vier Zeilen weiter dann: "das i-te Argument eines Arrays soll einen zufälligen Wert haben", aber wie groß ist i? Ohne Zuweisung durch Dich (oder eine Funktion o.ä.) ist das irgendein zufälliger Integer-Wert, also evtl. viel größer als die Länge des Arrays. Es fehlt also eine Zeile die so ähnlich aussieht:
ausblenden Delphi-Quelltext
1:
i:=...;					
wobei i nicht größer sein darf als die Länge des Arrays verringert um eins.

_________________
"Read the directions, even if you don't follow them.", Mary Schmich
JayEff
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2971

Windows Vista Ultimate
D7 Enterprise
BeitragVerfasst: Do 20.09.07 17:31 
user profile iconat4germany hat folgendes geschrieben:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
function TForm1.ArZahl:integer;

var j,i: integer;
    var arr : array of integer;
begin
setlength(arr, 65);
Arr[i]:= random(d);
for i:= 1 to d do
begin
  z:= random(d)+1;
  Arr[i]:=z;
  for j:= 1 to d do
  begin
   if z=Arr[i]
   then z:=random(d);
   end;
   result:=z;
end;
end;

Hier steht i als Zählvariable einer forschleife, die Zuweisung ist damit perfekt - Das Problem liegt daran, dass (wie wir schon gesagt haben!!) das dynamische Array von 0(!!) bis d-1 (!!!!) geht. Du weißt dem ersten Element nichts zu)was kein problem ist) und dafür einem nicht existierenden, 66ten Element! (zähl ruhig, von Nummer 0 bis Nummer 65 sind es 66 Elemente ;) )
Die Schleife muss also von 0 bis d-1 gehen.
Edit: Ah ja, da seh ichs, aus irgendeinem Grund weißt du noch vor der schleife einem Arr[i] eine Zahl zu. Lass diese Zeile weg (Wobei Integer i.d.R. mit 0 initialisiert werden)

_________________
>+++[>+++[>++++++++<-]<-]<++++[>++++[>>>+++++++<<<-]<-]<<++
[>++[>++[>>++++<<-]<-]<-]>>>>>++++++++++++++++++.+++++++.>++.-.<<.>>--.<+++++..<+.
at4germany Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 19



BeitragVerfasst: Do 20.09.07 17:57 
Ok, danke erstmal für die viele Hilfe ;-)
so, hab die Sachen geändert, die mir gesagt wurden. Die Fehlermeldung ist jetzt weg, aber ich bekomm immer noch als Deutsche Vokabel "9969432". Woran kann das liegen?

Hier nochmal der geänderte Quelltext für die Deutsche Vokabel:
ausblenden volle Höhe 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:
function TForm1.VokDeutsch: string;
var s: TStringList;
begin
s:= TStringList.Create;
s.LoadFromFile('D.txt');
d:= s.Count-1;  //Zählt die länge der Datei
Label7.Caption:=inttostr(d);
  try
  result:= s.Strings[d];
  finally
  s.free;
end;
end;

function TForm1.ArZahl:integer;
var j,i: integer;
    var arr : array of integer;
begin
setlength(arr, d);
for i:= 0 to d-1 do
begin
  z:= random(d)+1;
  Arr[i]:=z;
  for j:= 1 to d do
  begin
   if z=Arr[i]
   then z:=random(d);
   end;
   result:=z;
end;
end;


lg
Wonko
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 69



BeitragVerfasst: Fr 21.09.07 08:26 
Hey,
weitere mögliche Fehlerquellen:
  • Aufruf von Randomize vergessen?
  • z falsch deklariert (global)?
Hast Du Dich schon mal via Debugger schrittweise durch Deinen kompletten Code gehangelt? Dabei kann man toll überprüfen, wie lange die einzelnen Werte den Erwartungen entsprechen und wo Unsinn reinkommt.

Ich verstehe immer noch nicht den Sinn der folgenden Zeilen:
Zitat:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
Arr[i]:=z;
  for j:= 1 to d do
  begin
   if z=Arr[i]
   then z:=random(d);
   end;
Erst weist Du Arr[i] z zu und dann schaust Du, ob z gleich Arr[i] und änderst ggf. z???

@user profile iconJayEff: Bei mir ergibt
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
procedure TForm1.FormCreate(Sender: TObject);
var
  i:Integer;
begin
Label1.Caption:=IntToStr(i);
end;
definitiv nicht 0!

Grüße

_________________
"Read the directions, even if you don't follow them.", Mary Schmich
passiv
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 270

WIN XP Professional
Delphi 7 Enterprise, Java (Eclipse), Python 2.5, Django 1.1
BeitragVerfasst: Fr 21.09.07 11:18 
wenn ich das richtig verstanden hab, willst du mehr oder weniger lotto machen (oder wir haben das zumindest so gelernt). du musst dir das wie einen Kasten vorstellen (Kasten ist dann das arr: array ...) mit Schubladen mit der Aufschrift der Laufvariable (von arr[i]:=random(d)) und du kannst eine Lade entweder aufmachen oder schließen (arr: array of Boolean -> offen=true, geschlossen=false). so kannst du beim öffnen (also beim belegen) überprüfen (mittels simpelster if-Abfrage) ob denn die Lade eh noch nicht geöffnet ist. und hintendrein läufst du von vorne bis hinten durch und schreibst die zahlen (sortiert sind sie dann auch schon) in ein rein für die Zahlen zuständiges array.

also ich hoff, dass das nicht eine komplett an dem problem vorbeigehende Lösung ist

_________________
Die Probleme, die es in der Welt gibt, sind nicht mit der gleichen Denkweise zu lösen, die sie erzeugt hat.
Albert Einstein
at4germany Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 19



BeitragVerfasst: Fr 21.09.07 15:51 
Ok, also was ich vorhab ist:
Ich möchte via arr Z einen wert zuweisen.
Ob dieser schoneinmal zugewiesen wurde, wird via arr2 überprüft.
Also ich habe z.B. Werte von 0 - 60.
Diese werte sollen per random ausgewählt werden, aber es soll kein wert zweimla ausgwählt werden, d.h. ich bekomme bei der abfrage nicht zweimal den gleichen wert. Wenn ich also 60 vok. habe, sollen diese vokabeln zufällig ausgesucht werde, aber keine soll zweimal abgefragt werden.
So ich hoffe ich habe das jetzt verständlich erklärt ;-)

lg