Autor Beitrag
Sunsurfer79
Hält's aus hier
Beiträge: 6

Win 7
Delphi 6
BeitragVerfasst: Di 18.05.10 14:16 
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:

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:
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;
  //format(M);
end.
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.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.

_________________
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.
bummi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 1248
Erhaltene Danke: 187

XP - Server 2008R2
D2 - Delphi XE
BeitragVerfasst: Di 18.05.10 14:34 
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:
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 Threadstarter
Hält's aus hier
Beiträge: 6

Win 7
Delphi 6
BeitragVerfasst: 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. :-)

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:
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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 1248
Erhaltene Danke: 187

XP - Server 2008R2
D2 - Delphi XE
BeitragVerfasst: Di 18.05.10 16:20 
sorry :
ausblenden Delphi-Quelltext
1:
SetLength(result,high(M) + 1);					


Moderiert von user profile iconNarses: Delphi-Tags hinzugefügt
Tilo
ontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic starofftopic star
Beiträge: 1098
Erhaltene Danke: 13

Win7 geg. WInXP oder sogar Win98
Rad2007
BeitragVerfasst: Di 18.05.10 18:31 
user profile iconSunsurfer79 hat folgendes geschrieben Zum zitierten Posting springen:

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:
ausblenden 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:
ausblenden Delphi-Quelltext
1:
2:
for i:=low(arrayto high(arraydo
 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 Threadstarter
Hält's aus hier
Beiträge: 6

Win 7
Delphi 6
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic starofftopic star
Beiträge: 1098
Erhaltene Danke: 13

Win7 geg. WInXP oder sogar Win98
Rad2007
BeitragVerfasst: 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:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
Setlength(ArrayB,length(ArrayA));//=> Array B hat nun die gleiche Länge wie A. Vermutlich Definiert von 0 bis length-1
i2:=low(ArrayB); //initialisierung für den Durchlauf von ArrayB
for i1:=low(ArrayA) to high(ArrayA) do //=> vom kleinsten bis größten Index des ersten Arrays durchlaufen
begin
  ArrayB[i2]:=high(ArrayA[i1]);
  //weitere Aktionen
  inc(i2);
end;

Dieser Code hat den Vorteil, dass es egal ist wie die einzelnen Arrays vom Compiler definiert werden.