Entwickler-Ecke
Delphi Language (Object-Pascal) / CLX - 2-dimensionales Array befüllen
Sunsurfer79 - Di 18.05.10 14:16
Titel: 2-dimensionales Array befüllen
Hallo Zusammen.
Ich komme bei einer Aufgabe zu 2-dimensionalen Arrays nicht weiter.
Hier mal die Aufgabenstellung:
Schreiben Sie eine Funktion Format der als Parameter eine Variable M vom Typ
TMatrix übergeben wird. Der Funktionswert soll vom Typ TIntListe sein und die
Länge der einzelnen "Zeilen" von M enthalten.
Vorgaben:
TListe=array of Double,
TMatrix=array of TListe;
TIntListe=array of Integer;
Die Function "Format" zum Auslesen der Längen der Zeilen von M sollte soweit stimmen.
Ich schaffe es jedoch nicht das Array im Hauptprogramm zu befüllen, um es zu probieren.
Er schreibt mir die Zahlen alle untereinander
Es ist ja im Endeffekt ein Array of Array of double, oder?
Es soll eine Tabelle mit 10 Zeilen enstehen, die jedoch zufallsgesteuert verschieden lang sein sollen,
um dann die länge der einzelnen Zeilen als Funktionswerte zu erhalten.
Bsp:
xxxxx (5)
xxxxxxxxx (9)
xxxxxxx (7)
xxxxxxxxxxx (11)
(usw.)
Vielen Dank im Voraus.
MFG Sören
Hier der Quellcode:
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: 32: 33: 34: 35:
| program Aufgabe3;
{$APPTYPE CONSOLE}
uses SysUtils;
Type TListe=array of double; TMatrix=array of TListe; TIntListe=array of integer;
var M:TMatrix; i,j:integer; function format(M:TMatrix):TIntListe; var k:integer; begin for k:=0 to high(M) do begin result[k]:=length(M[k]); write(result[k]); readln; end; end;
begin randomize; setlength(M,10,random(10)+2); for i:=0 to high(M) do for j:=0 to high(M) do begin M[i,j]:=random(20); writeln(M[i,j]:2:0); end; readln; end. |
BenBE - Di 18.05.10 14:27
Durch dein ReadLn; werden Zeilenumbrüche in der Ausgabe erzeugt. Nehm das ml raus und schreib das am Ende deiner Hauptprozedur einmalig.
Ansonsten: SetLength mit 3 Argumenten setzt für jede der Zeilen die gleiche (im 3. Parameter gegebene) Länge. Wenn Du für jede Zeile was anderes haben willst, müsstest Du SetLength(M, 10); einmalig aufrufen gefolgt von SetLength(M[k], Random(10)); für jede einzelne Zeile k.
HTH.
bummi - Di 18.05.10 14:34
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: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44:
| program Aufgabe3;
{$APPTYPE CONSOLE}
uses SysUtils;
Type TListe=array of double; TMatrix=array of TListe; TIntListe=array of integer;
var M:TMatrix; i,j:integer; function format(M:TMatrix):TIntListe; var k:integer; begin SetLength(result,high(M)); for k:=0 to high(M) do begin result[k]:=High((M[k])) + 1; writeln(IntToStr(k) + ':' + IntToStr(result[k]));
end; end;
begin randomize; setlength(M,random(10)+2); for i:=0 to high(M) do begin setlength(M[i],random(10)+2);
for j:=0 to high(M[i]) do begin M[i,j]:=random(20); writeln(M[i,j]:2:0); end; end; writeln('Kommt'); format(M); readln;
end. |
Sunsurfer79 - Di 18.05.10 16:02
Danke für die Hilfestellungen.
ist es generell besser mit high statt length zu arbeiten? (Bsp: for i:=0 to high(M))
ist doch eigentlich das gleiche, oder?
Ich habe das Programm jetzt korrigiert und abgeändert. Leider stürzt es bei ca. jedem 3. Durchlauf mit "ungültige Zeigeroperation" ab. Ich weiß leider nicht, woran das liegen könnte.
Ich kriege auch die Ausgabe des 2-Dimensionalen Arrays in Tabellenform noch nicht hin. Er schreibt alles fleißig untereinander. Wenn die beiden Sachen noch behoben werden könnten, wäre es perfekt. :-)
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: 32: 33: 34: 35: 36: 37: 38: 39: 40:
| program Aufgabe3;
{$APPTYPE CONSOLE}
uses SysUtils;
Type TListe=array of double; TMatrix=array of TListe; TIntListe=array of integer;
var M:TMatrix; i,j:integer;
function format(M:TMatrix):TIntListe; var k:integer; begin SetLength(result,high(M)); for k:=0 to high(M) do begin result[k]:=high(M[k]); writeln(k+1:2,':',result[k]:3); end; end;
begin randomize; setlength(M,10); for i:=0 to high(M) do begin setlength(M[i],random(10)+5); for j:=0 to high(M[i]) do begin M[i,j]:=random(20); writeln(M[i,j]:2:0); end; end; writeln; format(M); readln; end. |
bummi - Di 18.05.10 16:20
sorry :
Delphi-Quelltext
1:
| SetLength(result,high(M) + 1); |
Moderiert von
Narses: Delphi-Tags hinzugefügt
Tilo - Di 18.05.10 18:31
Sunsurfer79 hat folgendes geschrieben : |
ist es generell besser mit high statt length zu arbeiten? (Bsp: for i:=0 to high(M))
ist doch eigentlich das gleiche, oder?
|
Nicht immer. In Verbindung mit Low() kannst Du bei Schleifen über Arrays ungekannter Größe sicher gehen das es zu keinen IndexOutOfRange kommt.
Ich hatte zum Beispiel mal ein Array von 1 bis 4 definiert.
In einer subfuntion schrieb ich folgendes:
Delphi-Quelltext
1: 2:
| for i:=1 to 4 do dosomethingwith(array[a]); |
Da die Funktion aber in einem anderem Kontext als die Arraydefinition lief und das Array als Parameter übergeben wurde (@all: bitte nicht hauhen) kam es zu einem IndexOutOfBounce.
Lösung war folgender Code:
Delphi-Quelltext
1: 2:
| for i:=low(array) to high(array) do dosomethingwith(array[a]); |
Grund: Durch die Übergabe als Parameter wurde der Indexraum des Arrays zu 0..3.
Low() und High() geben für arrays den kleinsten bzw größten Index zurück (klappt auch bei mehrdimensionalen Arrays).
High() entspricht Length()-1 bei Arrays solange du von 0 anfängst zu zählen.
Kleiner Spruch am Rande:
Es gibt folgende Leute, 1. die mit 1 anfangen zu zählen und 1. die mit 0 anfangen zu zählen.
Sunsurfer79 - Di 18.05.10 18:56
OK, danke,
Und warum funktioniert das Programm nicht ohne das +1?
SetLength(result,high(M)+1) = Das Array soll die Länge von M+1 annehmen also Index [0..10]
setlength(M,10) = Der Indexraum von M ist [0..9]
Warum braucht das Ergebnis-Array den einen Index mehr?
Tilo - Mi 19.05.10 08:58
Das ist einfach zu Erklären.
Du hast ein Array A, z.B. definiert von 1 bis 7 in der ersten Dimension und ein Array B definiert von 0 bis 7.
Low(A)=1, High(A)=7, Length(A)=7, Low(B)=0, High(B)=7, Length(B)=8
Der mathematische Zusammenhang zwischen Low(), High() und Length() ist: Length(x)=High(x)-Low(x)+1.
Im 2. Array möchteset Du nun den jeweiliges größten der 2. Dimension des ersten Arrays speichern. Bei einem Index von [0..6] wird ein 7-Elemente Arary benötigt.
Das sicherste vorgehen dürfte hier folgender Code sein:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8:
| Setlength(ArrayB,length(ArrayA));i2:=low(ArrayB); for i1:=low(ArrayA) to high(ArrayA) do begin ArrayB[i2]:=high(ArrayA[i1]); inc(i2); end; |
Dieser Code hat den Vorteil, dass es egal ist wie die einzelnen Arrays vom Compiler definiert werden.
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!