Textfile in Array einlesen und dann Ziehen ohne Zurücklegen

Für Fragen von Einsteigern und Programmieranfängern...
Antworten
Eva
Beiträge: 11
Registriert: Di 7. Aug 2012, 10:17

Textfile in Array einlesen und dann Ziehen ohne Zurücklegen

Beitrag von Eva »

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

indianer-frank
Beiträge: 134
Registriert: So 30. Nov 2008, 21:53

Re: Textfile in Array einlesen und dann Ziehen ohne Zurücklegen

Beitrag von indianer-frank »

Eva hat geschrieben: 45 Zufallsziehungen vornehmen, aber so, dass jedes Element genau 15 mal vorkommt (also jede Zeile nur einmal).

Toller Zufall.

Eva
Beiträge: 11
Registriert: Di 7. Aug 2012, 10:17

Re: Textfile in Array einlesen und dann Ziehen ohne Zurücklegen

Beitrag von Eva »

Die Reihenfolge soll zufällig sein.

Benutzeravatar
theo
Beiträge: 10497
Registriert: Mo 11. Sep 2006, 19:01

Re: Textfile in Array einlesen und dann Ziehen ohne Zurücklegen

Beitrag von theo »

TStringList ist hier sicher hilfreich.

MAC
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

Beitrag von MAC »

Du Läds das ganze in eine TStringList.
Berechnest ein Zufallswert:

Code: Alles auswählen

zufall := random(MyStringList.Count);


und dann gibts du den Wert aus und löschst den bisherigen eintrag:

Code: Alles auswählen

Memo1.Lines.Add(MyStringList.Strings[zufall]);
MyStringList.Delet(zufall);


und das ganze innerhalt dieser while schleife:

Code: Alles auswählen

While MyStringList.Count > 0 do
    begin
   // hier
   end;


Achtung, "PseudoCode" - incl Schreibfehler, excl.Deklarierungen...

Code: Alles auswählen

Signatur := nil;

Scotty
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

Beitrag von Scotty »

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.

u-boot
Beiträge: 306
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

Beitrag von u-boot »

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...
Ubuntu 9.10 (L 0.9.28 FPC 2.4.x)

indianer-frank
Beiträge: 134
Registriert: So 30. Nov 2008, 21:53

Re: Textfile in Array einlesen und dann Ziehen ohne Zurücklegen

Beitrag von indianer-frank »

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.

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
Beiträge: 11
Registriert: Di 7. Aug 2012, 10:17

Re: Textfile in Array einlesen und dann Ziehen ohne Zurücklegen

Beitrag von Eva »

Es hapert im Moment schon daran, ein Textfile in ein Array einzulesen.

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;

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

Benutzeravatar
theo
Beiträge: 10497
Registriert: Mo 11. Sep 2006, 19:01

Re: Textfile in Array einlesen und dann Ziehen ohne Zurücklegen

Beitrag von theo »

Eva hat geschrieben:Was ist hier falsch??


Wahrsch. werden deine Strings nicht automatisch zu Integers beim einlesen (Habe schon lange nicht mehr ge-readlnt)

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;

soerensen3
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

Beitrag von soerensen3 »

Warum nimmst du nicht eine TStringList?

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 ];

Wobei ich mir überlegen würde nicht einfach die StringList zu verwenden und auf das array zu verzichten.

Code: Alles auswählen

repeat
    Inc(i);
  until i=45;

Hm wozu ist das denn? :D

Eva
Beiträge: 11
Registriert: Di 7. Aug 2012, 10:17

Re: Textfile in Array einlesen und dann Ziehen ohne Zurücklegen

Beitrag von Eva »

Das ist ein Überbleibsel von ein paar Spielereien, die ich ausprobiert hab :lol:

mschnell
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

Beitrag von mschnell »

Eva hat geschrieben: 45 Zufallsziehungen vornehmen, aber so, dass jedes Element genau 15 mal vorkommt (also jede Zeile nur einmal).


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).

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

Antworten