Textfile in Array einlesen und dann Ziehen ohne Zurücklegen
Textfile in Array einlesen und dann Ziehen ohne Zurücklegen
Hallo!
Brauche nochmal eure Hilfe:
Ich habe ein Textfile mit 45 Zeilen, je 15 Zeilen enthalten den Namen eines (von 3) Stimuli. Jetzt möchte ich diese Elemente (strings) in ein Array einlesen und dann 45 Zufallsziehungen vornehmen, aber so, dass jedes Element genau 15 mal vorkommt (also jede Zeile nur einmal).
Habe leider noch keine Idee, deshalb auch noch keinen Code, den ich hier zur Diskussion stellen kann.
Wär toll, wenn jemand ne Idee hätt!
LG, Eva
Brauche nochmal eure Hilfe:
Ich habe ein Textfile mit 45 Zeilen, je 15 Zeilen enthalten den Namen eines (von 3) Stimuli. Jetzt möchte ich diese Elemente (strings) in ein Array einlesen und dann 45 Zufallsziehungen vornehmen, aber so, dass jedes Element genau 15 mal vorkommt (also jede Zeile nur einmal).
Habe leider noch keine Idee, deshalb auch noch keinen Code, den ich hier zur Diskussion stellen kann.
Wär toll, wenn jemand ne Idee hätt!
LG, Eva
-
- Beiträge: 134
- Registriert: So 30. Nov 2008, 21:53
Re: Textfile in Array einlesen und dann Ziehen ohne Zurücklegen
Toller Zufall.Eva hat geschrieben: 45 Zufallsziehungen vornehmen, aber so, dass jedes Element genau 15 mal vorkommt (also jede Zeile nur einmal).
Re: Textfile in Array einlesen und dann Ziehen ohne Zurücklegen
Die Reihenfolge soll zufällig sein.
Re: Textfile in Array einlesen und dann Ziehen ohne Zurücklegen
TStringList ist hier sicher hilfreich.
-
- Beiträge: 770
- Registriert: Sa 21. Feb 2009, 13:46
- OS, Lazarus, FPC: Windows 7 (L 1.3 Built 43666 FPC 2.6.2)
- CPU-Target: 32Bit
Re: Textfile in Array einlesen und dann Ziehen ohne Zurücklegen
Du Läds das ganze in eine TStringList.
Berechnest ein Zufallswert:
und dann gibts du den Wert aus und löschst den bisherigen eintrag:
und das ganze innerhalt dieser while schleife:
Achtung, "PseudoCode" - incl Schreibfehler, excl.Deklarierungen...
Berechnest ein Zufallswert:
Code: Alles auswählen
zufall := random(MyStringList.Count);
Code: Alles auswählen
Memo1.Lines.Add(MyStringList.Strings[zufall]);
MyStringList.Delet(zufall);
Code: Alles auswählen
While MyStringList.Count > 0 do
begin
// hier
end;
Code: Alles auswählen
Signatur := nil;
-
- Beiträge: 768
- Registriert: Mo 4. Mai 2009, 13:24
- OS, Lazarus, FPC: Arch Linux, Lazarus 1.3 r44426M FPC 2.6.4
- CPU-Target: x86_64-linux-qt/gtk2
- Kontaktdaten:
Re: Textfile in Array einlesen und dann Ziehen ohne Zurücklegen
Theo hat hier mal einen genialen Vorschlag zum randomisieren von Listen gemacht.
Code: Alles auswählen
<TList.>Sort(@RandomSort);
function RandomSort(...)
begin
Result := -1 + random(3);
end;
Zuletzt geändert von Scotty am Sa 25. Aug 2012, 10:57, insgesamt 1-mal geändert.
-
- Beiträge: 308
- Registriert: Do 9. Apr 2009, 10:10
- OS, Lazarus, FPC: Ubuntu 9.10 (L 0.9.28 FPC 2.2.4)
- CPU-Target: 32Bit
- Wohnort: 785..
Re: Textfile in Array einlesen und dann Ziehen ohne Zurücklegen
Gibt viele verschiedene Ansätze Elemente zufällig anordnen zu lassen. Ich sag nicht, dass alle elegant sind.
Hier mal paar Ansätze die mir grad einfallen:
1. Man lasse bei einer sortierten Liste Elemente zufällig vertauschen.
2. Man setze nur ein Element in eine Liste und lässt jedes weitere Element an einer zufälligen Stelle einfügen.
3. Man weist dem ersten element zufällig ein Platz zu, dem 2. dann zufällig einen der übrigen Plätze usw.: anstrengend rauszufinden, welcher Platz mit einer Zufallszahl dann gemeint ist, aber geht ...
4. Man zieht zufällig einen Platz für jedes Element. Ist der Platz schon belegt wird einfach nochmal gezogen.... kann dann irgendwann durchaus bissl dauern...
Hier mal paar Ansätze die mir grad einfallen:
1. Man lasse bei einer sortierten Liste Elemente zufällig vertauschen.
2. Man setze nur ein Element in eine Liste und lässt jedes weitere Element an einer zufälligen Stelle einfügen.
3. Man weist dem ersten element zufällig ein Platz zu, dem 2. dann zufällig einen der übrigen Plätze usw.: anstrengend rauszufinden, welcher Platz mit einer Zufallszahl dann gemeint ist, aber geht ...
4. Man zieht zufällig einen Platz für jedes Element. Ist der Platz schon belegt wird einfach nochmal gezogen.... kann dann irgendwann durchaus bissl dauern...
Ubuntu 9.10 (L 0.9.28 FPC 2.4.x)
-
- Beiträge: 134
- Registriert: So 30. Nov 2008, 21:53
Re: Textfile in Array einlesen und dann Ziehen ohne Zurücklegen
Also willst Du eigentlich gar nicht "ziehen" sondern mischen bzw. eine Zufallspermutation erzeugen. Dazu gibt's es eine seit Jahrzehnten allgemein anerkannte Prozedur: Fisher-Yates-Shuffle.Eva hat geschrieben: 45 Zufallsziehungen vornehmen, aber so, dass jedes Element genau 15 mal vorkommt (also jede Zeile nur einmal).
...
Die Reihenfolge soll zufällig sein.
Re: Textfile in Array einlesen und dann Ziehen ohne Zurücklegen
Es hapert im Moment schon daran, ein Textfile in ein Array einzulesen.
Was ist hier falsch??
Wenn ich das so mache bekomme ich die Fehlermeldung: "project1.exe hat Exception-Klasse "RunError(59584)" ausgelöst.
Versteh ich nicht ... (liegt vielleicht an meinem Anfängerdasein, aber Hilfe wär toll!!)
Eva
Was ist hier falsch??
Code: Alles auswählen
var
Form1: TForm1;
stim: array [1..3] of string;
numlist: array [1..45] of Integer; // Die numlist ist ein Textfile mit 45 Zeilen, die je 15 mal
num: Integer; // die Zahlen 1 bis 3 enthalten (steht dann später für den Stimulus).
F: TextFile;
procedure TForm1.Button1Click(Sender: TObject);
var i: Integer=0;
begin
stim[1]:='kreis';
stim[2]:='stern';
stim[3]:='dreieck';
repeat
Inc(i);
until i=45;
AssignFile(F,'45.txt');
Reset(F);
for i:=1 to 45 do
Readln(F,numlist[i]);
CloseFile(F);
num:=numlist[45]; // Nur so als Beispiel, hier würde dann später zufällig ein Element aus dem Array gezogen werden.
Form1.Caption:=stim[num];
Image1.Picture.LoadFromFile(stim[num]+'.bmp');
Image1.Visible:=True;
end;
Versteh ich nicht ... (liegt vielleicht an meinem Anfängerdasein, aber Hilfe wär toll!!)
Eva
Re: Textfile in Array einlesen und dann Ziehen ohne Zurücklegen
Wahrsch. werden deine Strings nicht automatisch zu Integers beim einlesen (Habe schon lange nicht mehr ge-readlnt)Eva hat geschrieben: Was ist hier falsch??
Aber warum nimmst du nicht wie vorgeschlagen eine TStringList und deren Methode Loadfromfile ?
Was hat das für einen Zweck?
Code: Alles auswählen
repeat
Inc(i);
until i=45;
-
- Beiträge: 104
- Registriert: Fr 22. Jun 2012, 01:51
- OS, Lazarus, FPC: Fedora-Linux 23 (Korora) Lazarus 1.6 FPC 3.0
- CPU-Target: 64Bit
- Wohnort: Bonn
Re: Textfile in Array einlesen und dann Ziehen ohne Zurücklegen
Warum nimmst du nicht eine TStringList?
Wobei ich mir überlegen würde nicht einfach die StringList zu verwenden und auf das array zu verzichten.
Hm wozu ist das denn? 
Code: Alles auswählen
F: TStringList;
...
F.LoadFromFile( ..);
for i:= 0 to Min( 44, F.Count -1 ) do // Maximal bis 44
numlist[ i + 1]:= F[ i ];
Code: Alles auswählen
repeat
Inc(i);
until i=45;

Re: Textfile in Array einlesen und dann Ziehen ohne Zurücklegen
Das ist ein Überbleibsel von ein paar Spielereien, die ich ausprobiert hab 

-
- Beiträge: 3444
- Registriert: Mo 11. Sep 2006, 10:24
- OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
- CPU-Target: X32 / X64 / ARMv5
- Wohnort: Krefeld
Re: Textfile in Array einlesen und dann Ziehen ohne Zurücklegen
1) Bitte zuerst mit Zahlen arbeiten (z.B. 1, 2, 3) am Schluss wählt dann die Zahl einen String aus einem "Array of String" aus. Unnötiger weise Strings durch den vorhergehenden Algorithmus zu schleusen ist kontra-produktiv (oder zumindest schlechter Stil weil Speicherplatz und Rechenzeit vergeudet werden).Eva hat geschrieben: 45 Zufallsziehungen vornehmen, aber so, dass jedes Element genau 15 mal vorkommt (also jede Zeile nur einmal).
2) Zufallszahlen ohne zurücklegen:
Du machst eine TList von Paaren Record oder TObject n: integer; z: real;
Dann füllst Du die n's mit Deinen zahlen (15* 1, 15*2, 15*3)
Dann füllst Du z's mit Zufallszahlen.
Dann benutzt Du TList.Sort um nach den z's zu sortieren.
Die n's sind dann in zufälliger Reihenfolge.
-Michael