2.7 Felder (Arrays) - Universität Paderborn

Werbung
2.7 Felder (Arrays)
¾
»
Felder (Arrays) bilden eine Zusammenfassung von Elementen gleichen Typs,
deren Anzahl bei der Programmierung noch nicht notwendigerweise feststeht.
½
¼
Das englische Wort “array” hatte ursprünglich militärische Bedeutung: “Aufstellung zur Schlacht”:
Titel der Zeichnung links:
Bataille, welche Ihr Königl. Majst. von
Schweden bei Belägerung Kopenhagen
den 29. Oktobr. 1659 in ein Lager
gesetzt und selbige Stadt damahls biß
den 27 Mai 1660 blokiret gewesen
Schlachtaufstellung der Schweden bei Kopenhagen, 1659, Handzeichnung
Rainer Feldmann
Universität Paderborn
Technische Informatik für Ingenieure (TIFI)
WS 09/10
112
Arrays
• ein Array ist eine Tabelle gleichartiger Elemente, d.h. die Elemente haben den gleichen Typ.
• Die Tabelle hat einen Namen, die einzelnen Elemente werden über eine Indizierung angesprochen.
a[0]
a[1]
a[2]
a[3]
a[4]
a[5]
...
a
²
¯
In Java sind die Elemente eines Arrays Variablen, die alle den gleichen Typ haben.
±
Rainer Feldmann
Universität Paderborn
°
Technische Informatik für Ingenieure (TIFI)
WS 09/10
113
Das Sieb des Eratosthenes
Problem Primzahlen:
geg: n ∈ N
ges: alle Primzahlen ≤ n
Idee:
1. Schreibe alle Zahlen 2, . . . , n in ein Array.
2. 2 ist eine Primzahl: streiche alle Vielfachen von 2.
3. die kleinste nicht gestrichene Zahl ist 3. 3 ist eine Primzahl:
streiche alle Vielfachen von 3.
4. die kleinste nicht gestrichene Zahl ist 5. 5 ist eine Primzahl:
usw.
Eratosthenes
276 - 194 v.Chr. (?)
»
¾
Nichtprimzahlen fallen durch ein Sieb“.
”
Die Zahlen, die im Sieb verbleiben, sind Primzahlen.
½
Rainer Feldmann
Universität Paderborn
¼
Technische Informatik für Ingenieure (TIFI)
WS 09/10
114
Das Sieb des Eratosthenes
schrittweise Implementierung
/* Nach Ausführung enthält das Array "sieb" im Element sieb[i] entweder i, wenn i */
/* Primzahl ist, oder einen echten Primteiler von i, wenn i keine Primzahl ist */
int n = In.readInt();
int[] sieb = new int[n+1];
Rainer Feldmann
Universität Paderborn
/* lese Obergrenze für Primzahlen */
/* reserviere Platz für n+1 Zahlen sieb[0],...,sieb[n] */
Technische Informatik für Ingenieure (TIFI)
WS 09/10
115
Das Sieb des Eratosthenes
schrittweise Implementierung
/* Nach Ausführung enthält das Array "sieb" im Element sieb[i] entweder i, wenn i */
/* Primzahl ist, oder einen echten Primteiler von i, wenn i keine Primzahl ist */
int n = In.readInt();
int[] sieb = new int[n+1];
/* lese Obergrenze für Primzahlen */
/* reserviere Platz für n+1 Zahlen sieb[0],...,sieb[n] */
for (int i = 2; i <= n; i++) sieb[i] = i;
Rainer Feldmann
Universität Paderborn
/* initialisiere sieb[i] = i */
Technische Informatik für Ingenieure (TIFI)
WS 09/10
115
Das Sieb des Eratosthenes
schrittweise Implementierung
/* Nach Ausführung enthält das Array "sieb" im Element sieb[i] entweder i, wenn i */
/* Primzahl ist, oder einen echten Primteiler von i, wenn i keine Primzahl ist */
int n = In.readInt();
int[] sieb = new int[n+1];
/* lese Obergrenze für Primzahlen */
/* reserviere Platz für n+1 Zahlen sieb[0],...,sieb[n] */
for (int i = 2; i <= n; i++) sieb[i] = i;
for (int i = 2; i <= n; i++) {
/* initialisiere sieb[i] = i */
/* solange noch Zahlen i zu testen sind ... */
} // for all i <= n ...
Rainer Feldmann
Universität Paderborn
Technische Informatik für Ingenieure (TIFI)
WS 09/10
115
Das Sieb des Eratosthenes
schrittweise Implementierung
/* Nach Ausführung enthält das Array "sieb" im Element sieb[i] entweder i, wenn i */
/* Primzahl ist, oder einen echten Primteiler von i, wenn i keine Primzahl ist */
int n = In.readInt();
int[] sieb = new int[n+1];
/* lese Obergrenze für Primzahlen */
/* reserviere Platz für n+1 Zahlen sieb[0],...,sieb[n] */
for (int i = 2; i <= n; i++) sieb[i] = i;
for (int i = 2; i <= n; i++) {
/* initialisiere sieb[i] = i */
/* solange noch Zahlen i zu testen sind ... */
if (sieb[i]==i) {
Out.println(i);
/* i ist Primzahl */
} // if ...
} // for all i <= n ...
Rainer Feldmann
Universität Paderborn
Technische Informatik für Ingenieure (TIFI)
WS 09/10
115
Das Sieb des Eratosthenes
schrittweise Implementierung
/* Nach Ausführung enthält das Array "sieb" im Element sieb[i] entweder i, wenn i */
/* Primzahl ist, oder einen echten Primteiler von i, wenn i keine Primzahl ist */
int n = In.readInt();
int[] sieb = new int[n+1];
/* lese Obergrenze für Primzahlen */
/* reserviere Platz für n+1 Zahlen sieb[0],...,sieb[n] */
for (int i = 2; i <= n; i++) sieb[i] = i;
for (int i = 2; i <= n; i++) {
/* initialisiere sieb[i] = i */
/* solange noch Zahlen i zu testen sind ... */
if (sieb[i]==i) {
Out.println(i);
for (int j = 2*i; j <= n; j=j+i)
sieb[j] = i;
/* i ist Primzahl */
/* markiere echte Vielfache von i */
/* i<j ist echter Primteiler von j */
} // if ...
} // for all i <= n ...
Rainer Feldmann
Universität Paderborn
Technische Informatik für Ingenieure (TIFI)
WS 09/10
115
Das Sieb des Eratosthenes
Deklaration eines Arrays
/* Nach Ausführung enthält das Array "sieb" im Element sieb[i] entweder i, wenn i */
/* Primzahl ist, oder einen echten Primteiler von i, wenn i keine Primzahl ist */
int n = In.readInt();
int[] sieb = new int[n+1];
/* lese Obergrenze für Primzahlen */
/* reserviere Platz für n+1 Zahlen sieb[0],...,sieb[n] */
for (int i = 2; i <= n; i++) sieb[i] = i;
for (int i = 2; i <= n; i++) {
/* initialisiere sieb[i] = i */
/* solange noch Zahlen i zu testen sind ... */
if (sieb[i]==i) {
Out.println(i);
for (int j = 2*i; j <= n; j=j+i)
sieb[j] = i;
/* i ist Primzahl */
/* markiere echte Vielfache von i */
/* i<j ist echter Primteiler von j */
} // if ...
} // for all i <= n ...
Rainer Feldmann
Universität Paderborn
Technische Informatik für Ingenieure (TIFI)
WS 09/10
115
Das Sieb des Eratosthenes
Zuweisung an Arrayelemente
/* Nach Ausführung enthält das Array "sieb" im Element sieb[i] entweder i, wenn i */
/* Primzahl ist, oder einen echten Primteiler von i, wenn i keine Primzahl ist */
int n = In.readInt();
int[] sieb = new int[n+1];
/* lese Obergrenze für Primzahlen */
/* reserviere Platz für n+1 Arrayelemente 0,...,n */
for (int i = 2; i <= n; i++) sieb[i] = i;
for (int i = 2; i <= n; i++) {
/* initialisiere sieb[i] = i */
/* solange noch Zahlen i zu testen sind ... */
if (sieb[i]==i) {
Out.println(i);
for (int j = 2*i; j <= n; j=j+i)
sieb[j] = i;
/* i ist Primzahl */
/* markiere echte Vielfache von i */
/* i<j ist echter Primteiler von j */
} // if ...
} // for all i <= n ...
Rainer Feldmann
Universität Paderborn
Technische Informatik für Ingenieure (TIFI)
WS 09/10
115
Das Sieb des Eratosthenes
Abfrage von Arrayelmenten
/* Nach Ausführung enthält das Array "sieb" im Element sieb[i] entweder i, wenn i */
/* Primzahl ist, oder einen echten Primteiler von i, wenn i keine Primzahl ist */
int n = In.readInt();
int[] sieb = new int[n+1];
/* lese Obergrenze für Primzahlen */
/* reserviere Platz für n+1 Arrayelemente 0,...,n */
for (int i = 2; i <= n; i++) sieb[i] = i;
for (int i = 2; i <= n; i++) {
/* initialisiere sieb[i] = i */
/* solange noch Zahlen i zu testen sind ... */
if (sieb[i]==i) {
Out.println(i);
for (int j = 2*i; j <= n; j=j+i)
sieb[j] = i;
/* i ist Primzahl */
/* markiere echte Vielfache von i */
/* i<j ist echter Primteiler von j */
} // if ...
} // for all i <= n ...
Rainer Feldmann
Universität Paderborn
Technische Informatik für Ingenieure (TIFI)
WS 09/10
115
Das Sieb des Eratosthenes
Operationen mit Array
/* Nach Ausführung enthält das Array "sieb" im Element sieb[i] entweder i, wenn i */
/* Primzahl ist, oder einen echten Primteiler von i, wenn i keine Primzahl ist */
int n = In.readInt();
int[] sieb = new int[n+1];
/* lese Obergrenze für Primzahlen */
/* reserviere Platz für n+1 Arrayelemente 0,...,n */
for (int i = 2; i <= n; i++) sieb[i] = i;
for (int i = 2; i <= n; i++) {
/* initialisiere sieb[i] = i */
/* solange noch Zahlen i zu testen sind ... */
if (sieb[i]==i) {
Out.println(i);
for (int j = 2*i; j <= n; j=j+i)
sieb[j] = i;
/* i ist Primzahl */
/* markiere echte Vielfache von i */
/* i<j ist echter Primteiler von j */
} // if ...
} // for all i <= n ...
Rainer Feldmann
Universität Paderborn
Technische Informatik für Ingenieure (TIFI)
WS 09/10
115
Deklaration von Arrays
int[ ] sieb;
/* Deklaration einer Arrayvariablen "sieb" */
/* mit unbestimmter Anzahl von int-Elementen */
Damit: BNF-Produktionen für Typdefinition:
<Typ>
<primitiveType>
<complexType>
<arrayType>
::=
::=
::=
::=
<primitiveType> | <complexType> | <arrayType>
int | long | byte | short| double | float | char | boolean
String | ...
<Typ>[ ]
»
¾
Nach der Deklaration einer Arrayvariablen unbestimmter
Länge existiert noch kein Element des Arrays!
½
Rainer Feldmann
Universität Paderborn
¼
Technische Informatik für Ingenieure (TIFI)
WS 09/10
116
Erzeugung von Arrays mit new und Längenabfrage
int[ ] sieb;
sieb = new int[n+1];
/* Deklaration der Arrayvariablen "sieb" */
/* Erzeugung von n+1 Arrayelementen vom Typ int */
int[ ] sieb = new int[n+1];
/* Deklaration und Erzeugung */
¾
»
Arrayelemente werden durchnumeriert“.
”
Die Numerierung beginnt immer bei 0.
½
¼
• Die Länge eines Arrays ist definiert als die Anzahl der Elemente im Array und kann jederzeit
im Programm abgefragt werden:
int[ ] sieb = new int[n+1];
int m = sieb.length ...
Rainer Feldmann
Universität Paderborn
/* Deklaration und Erzeugung */
/* jetzt ist m = n+1 */
Technische Informatik für Ingenieure (TIFI)
WS 09/10
117
Arraytyp
• Arrayvariablen haben den Arraytyp <Typ>[ ]“.
”
• Arrayvariablen gleichen Arraytyps können aufeinander zugewiesen werden.
• Arrayvariablen sind Zeiger auf einen Speicherbereich. Durch Zuweisung ändert sich die Speicherzelle, auf die das Array zeigt:
int[ ] a;
int[ ] b;
Speicher
/* Deklaration */
/* b und a haben gleichen Typ int[] */
b
a
Rainer Feldmann
Universität Paderborn
Technische Informatik für Ingenieure (TIFI)
WS 09/10
118
Arraytyp
• Arrayvariablen haben den Arraytyp <Typ>[ ]“.
”
• Arrayvariablen gleichen Arraytyps können aufeinander zugewiesen werden.
• Arrayvariablen sind Zeiger auf einen Speicherbereich. Durch Zuweisung ändert sich die Speicherzelle, auf die das Array zeigt:
int[ ] a = new int[5];
int[ ] b = new int[3];
Speicher
0
a
/* Deklaration und Erzeugung */
/* b und a haben gleichen Typ int[] */
b
1
2
3
4
0 0 0 0 0
Rainer Feldmann
Universität Paderborn
0
1
2
0 0 0
Technische Informatik für Ingenieure (TIFI)
WS 09/10
118
Arraytyp
• Arrayvariablen haben den Arraytyp <Typ>[ ]“.
”
• Arrayvariablen gleichen Arraytyps können aufeinander zugewiesen werden.
• Arrayvariablen sind Zeiger auf einen Speicherbereich. Durch Zuweisung ändert sich die Speicherzelle, auf die das Array zeigt:
int[ ] a = new int[5];
/* Deklaration und Erzeugung
int[ ] b = new int[3];
/* b und a haben gleichen Typ int[]
for (int i = 0; i < a.length; i++) a[i] = i+10; /* init(a)
for (int i = 0; i < b.length; i++) b[i] = i+20; /* init(b)
Speicher
0
a
*/
*/
*/
*/
b
1
2
3
4
10 11 12 13 14
Rainer Feldmann
Universität Paderborn
0
1
2
20 21 22
Technische Informatik für Ingenieure (TIFI)
WS 09/10
118
Arraytyp
• Arrayvariablen haben den Arraytyp <Typ>[ ]“.
”
• Arrayvariablen gleichen Arraytyps können aufeinander zugewiesen werden.
• Arrayvariablen sind Zeiger auf einen Speicherbereich. Durch Zuweisung ändert sich die Speicherzelle, auf die das Array zeigt:
int[ ] a = new int[5];
/* Deklaration und Erzeugung
int[ ] b = new int[3];
/* b und a haben gleichen Typ int[]
for (int i = 0; i < a.length; i++) a[i] = i+10; /* init(a)
for (int i = 0; i < b.length; i++) b[i] = i+20; /* init(b)
a = b;
/* Zuweisung einer neuen Adresse an a
Speicher
0
a
*/
*/
*/
*/
*/
b
1
2
3
4
10 11 12 13 14
Rainer Feldmann
Universität Paderborn
0
1
2
20 21 22
Technische Informatik für Ingenieure (TIFI)
WS 09/10
118
Arraytyp
• Arrayvariablen haben den Arraytyp <Typ>[ ]“.
”
• Arrayvariablen gleichen Arraytyps können aufeinander zugewiesen werden.
• Arrayvariablen sind Zeiger auf einen Speicherbereich. Durch Zuweisung ändert sich die Speicherzelle, auf die das Array zeigt:
int[ ] a = new int[5];
/* Deklaration und Erzeugung
int[ ] b = new int[3];
/* b und a haben gleichen Typ int[]
for (int i = 0; i < a.length; i++) a[i] = i+10; /* init(a)
for (int i = 0; i < b.length; i++) b[i] = i+20; /* init(b)
a = b;
/* Zuweisung einer neuen Adresse an a
*/
*/
*/
*/
*/
'
Speicher
b
Das Array, auf das a zeigte,
0
a
10 11 12 13 14
$
1
2
20 21 22
kann nie wieder referenziert werden. Sein Speicherplatz wird vom
Java-System freigegeben.
&
Rainer Feldmann
Universität Paderborn
Technische Informatik für Ingenieure (TIFI)
%
WS 09/10
118
Zugriff auf Arrayelemente
• Arrayelemente sind indiziert. Auf sie kann mit <Array>[<Index>] zugegriffen werden. Dabei
muss der Typ des Index ganzzahlig sein, d.h. int, long, short, byte.
sieb[i] = ... ; sieb[i%j+k] = ... ;
• Um auf alle Elemente eines Arrays zuzugreifen eignet sich besonders die for-Schleife:
for (i = 0; i < sieb.length; i++) sieb[i] = ...
• Arrayelemente können wie einfache“ Variablen gleichen Typs verwendet werden:
”
sieb[i] = i;
if (sieb[i] == i) ...
p = sieb[i]/sieb[j]; q = sieb[i] % sieb[j];
p = p+sieb[j]; ...
for (sieb[i] = 0; sieb[i] <= i; sieb[i]++) ...
Rainer Feldmann
Universität Paderborn
Technische Informatik für Ingenieure (TIFI)
/* Zuweisung */
/* Ausdruck */
/* Operationen für int */
/* unschön */
WS 09/10
119
Initialisierung von Arrayelementen
• Nach new haben alle Arrayelemente den Wert 0 (Achtung: Die Elemente sind nicht immer
ganze Zahlen. Es werden alle Bits auf 0 gesetzt!)
• Ist die Anzahl der Elemente zum Zeitpunkt der Programmentwicklung noch nicht bekannt,
können die Arrayelemente mit einer Schleife initialisiert werden:
int n = In.readInt();
int[ ] sieb = new int[n+1];
for (i = 0; i < sieb.length; i++) sieb[i] = i;
• Sind die Anzahl der Elemente und ihre initialen Werte zum Zeitpunkt der Programmentwicklung
bekannt, kann das Array schon mit der new-Anweisung initialisiert werden:
String[] monat = new String[] {
"Jan", "Feb", "Mär", "Apr", "Mai", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dez"
}
Rainer Feldmann
Universität Paderborn
Technische Informatik für Ingenieure (TIFI)
WS 09/10
120
Mehrdimensionale Arrays
• Ein Array ist eine Tabelle gleichartiger Elemente.
• Sind diese gleichartigen Elemente wieder Arrays, so erhält man mehrdimensionale Arrays.
a
a[0][0]
a[0][4]
a[0]
0
1
2
3
4
a[1]
5
6
7
8
9
a[2]
10
11
12
13
14
a[2][0]
Rainer Feldmann
Universität Paderborn
a[2][4]
Das Beispiel links zeigt eine 2-dimensionale Tabelle,
oder Matrix.
int[][] a;
/* Deklaration */
a = new int[3][5];
/* Erzeugung */
for (int i = 0; i < a.length; i++)
for (int j = 0; j < a[i].length; j++)
a[i][j] = 5*i+j; /* Initialisierung */
/* oder */
int[][] a = {{0,1,2,3,4},
{5,6,7,8,9},
{10,11,12,13,14}};
Technische Informatik für Ingenieure (TIFI)
WS 09/10
121
Beispiel: Transponieren einer Matrix
Es seien m, n ∈ N. Eine m × n Matrix A über den reellen Zahlen R (A ∈ Rm×n) ist eine
2-dimensionale Tabelle mit m Zeilen und n Spalten über R. Die Elemente von A werden mit
Ai,j , 0 ≤ i ≤ m − 1, 0 ≤ j ≤ n − 1 bezeichnet.
Zu einer Matrix A ∈ Rm×n ist die Transponierte AT ∈ Rn×m definiert durch
T
Ai,j = Aj,i 0 ≤ i ≤ n − 1, 0 ≤ j ≤ m − 1
Beispiel:
0
1
A=@ 4
7
2
5
8
1
0
3
1
T
6 A, A = @ 2
9
3
4
5
6
1
7
`
8 A, B = 1
9
0
2
3
´
1
1
, B =@ 2 A
3
T
Die Transponierte einer Matrix entsteht durch Spiegelung der Elemente an der Hauptdiagonalen“.
”
Rainer Feldmann
Universität Paderborn
Technische Informatik für Ingenieure (TIFI)
WS 09/10
122
Beispiel: Transponieren einer Matrix
Problem Transponierte:
geg: n ∈ N, A ∈ Rn×n
ges: AT
Es ist ATi,j = Aj,i für alle i, j . Also: vertausche die
Elemente unterhalb der Hauptdiagonalen mit den entsprechenden Elementen überhalb der Hauptdiagonalen.
/* wandelt eine quadratische Matrix A ∈ Rn×n in AT um */
int n = In.readInt();
float a[][] = new int[n][n];
...
for (int i = 0; i < a.length; i++)
for (int j = 0; j < i; j++) {
float h;
/* vertausche Ai,j und Aj,i */
h = a[i][j]; a[i][j] = a[j][i]; a[j][i] = h;
}
Rainer Feldmann
Universität Paderborn
Technische Informatik für Ingenieure (TIFI)
WS 09/10
123
Beispiel: Matrixmultiplikation
Es seien m, n, k ∈ N, A ∈ Rm×n, B ∈ Rn×k . Dann ist das Matrixprodukt C= A · B ∈ Rm×k
definiert durch
Ci,j =
n−1
X
Ai,p · Bp,j , 0 ≤ i ≤ n − 1, 0 ≤ j ≤ k − 1
p=0
/* seien die Matrizen a und b schon eingelesen */
float[][] c = new float[a.length][b[0].length];
/* Dimens. beachten */
for (int i = 0; i < a.length; i++)
for (int j = 0; j < b[0].length; j++) {
c[i][j] = 0;
for (int p = 0; p < b.length; p++)
c[i][j] = c[i][j] + a[i][p]*b[p][j];
}
Rainer Feldmann
Universität Paderborn
/* initialisiere mit 0 */
Technische Informatik für Ingenieure (TIFI)
/* addiere Summanden */
WS 09/10
124
Beispiel: Adjazenzmatrix eines Graphen
Ein (gerichteter) Graph G = (V, E) besteht aus einer Knotenmenge V und einer Kantenmenge
E ⊆ V ×V.
Graphen können gezeichnet“
”
werden: Knoten sind Punkte,
Kanten sind Linien.
0
1
3
2
Rainer Feldmann
Universität Paderborn
Technische Informatik für Ingenieure (TIFI)
WS 09/10
125
Beispiel: Adjazenzmatrix eines Graphen
Ein (gerichteter) Graph G = (V, E) besteht aus einer Knotenmenge V und einer Kantenmenge
E ⊆ V ×V.
Graphen können gezeichnet“
”
werden: Knoten sind Punkte,
Kanten sind Linien.
0
1
3
2
Rainer Feldmann
Universität Paderborn
Es sei G = (V, E) ein Graph, n = |V |.
Die Adjazenzmatrix A ∈ {0, 1}n×n ist definiert durch
Ai,j = 1 ⇔ (i, j) ∈ E
Technische Informatik für Ingenieure (TIFI)
WS 09/10
125
Beispiel: Adjazenzmatrix eines Graphen
Ein (gerichteter) Graph G = (V, E) besteht aus einer Knotenmenge V und einer Kantenmenge
E ⊆ V ×V.
Graphen können gezeichnet“
”
werden: Knoten sind Punkte,
Kanten sind Linien.
0
1
Es sei G = (V, E) ein Graph, n = |V |.
Die Adjazenzmatrix A ∈ {0, 1}n×n ist definiert durch
Ai,j = 1 ⇔ (i, j) ∈ E
Ein Graph G mit n Knoten kann im Computer dargestellt werden, indem man seine Adjazenzmatrix speichert:
0
0
B 0
A=B
@ 0
1
3
Rainer Feldmann
Universität Paderborn
1
0
0
1
0
1
0
0
1
0
0 C
C
1 A
0
ist die Adjazenzmatrix des
Graphen links.
2
Technische Informatik für Ingenieure (TIFI)
WS 09/10
125
Beispiel: Adjazenzmatrix eines Graphen
Ein (gerichteter) Graph G = (V, E) besteht aus einer Knotenmenge V und einer Kantenmenge
E ⊆ V ×V.
Graphen können gezeichnet“
”
werden: Knoten sind Punkte,
Kanten sind Linien.
0
1
Es sei G = (V, E) ein Graph, n = |V |.
Die Adjazenzmatrix A ∈ {0, 1}n×n ist definiert durch
Ai,j = 1 ⇔ (i, j) ∈ E
Ein Graph G mit n Knoten kann im Computer dargestellt werden, indem man seine Adjazenzmatrix speichert:
0
0
B 0
A=B
@ 0
1
3
Rainer Feldmann
Universität Paderborn
2
1
0
0
1
0
1
0
0
1
0
0 C
C
1 A
0
ist die Adjazenzmatrix des
Graphen links.
¾
»
Transponieren der Adjazenzmatrix von G ist äquivalent
zum Umdrehen“ der Kanten von G.
”
½
¼
Technische Informatik für Ingenieure (TIFI)
WS 09/10
125
Beispiel: Wegeberechnung in Graphen
Es sei G = (V, E) ein Graph, A die Adjazenzmatrix von G, Ak = A
. . · A}, k ∈ N.
| · .{z
k-mal
Dann gilt:
k
es existiert ein Weg von i nach j in G ⇔ es existiert k ∈ N0 : Ai,j > 0
0
3
Rainer Feldmann
Universität Paderborn
1
2
0
0
1
0
0
0
0
1
0
1
0
0 C
C,
0 A
1
0
0
0
1
1
1
0
0
1
1
0
1 C
C,
0 A
0
1
B
0
0
A =B
@ 0
0
0
B
0
2
A =B
@ 1
0
Technische Informatik für Ingenieure (TIFI)
0
1
0
0
1
0
1
0
0
1
0
0 C
C,
1 A
0
0
0
1
1
0
0
0
1
1
1
1
0 C
C
0 A
1
0
B
0
1
A =B
@ 0
1
0
B
1
3
A =B
@ 0
0
WS 09/10
126
Beispiel: Sudoku-Spiel
6
9
7
1
2
8
6
6
7
3
9
2
8
7
5
1
3
4
9
9
3
4
9
2
8
5
Rainer Feldmann
Universität Paderborn
4
Das Spiel ist gelöst, wenn alle Felder so
mit Zahlen gefüllt sind, daß in jeder Zeile,
in jeder Spalte und in jedem Teilquadrat
jede Zahl aus {1, . . . , 9} genau einmal
vorkommt.
(Siehe auch http://www.sudoku-lobby.de)
Wir wollen berechnen, welche Zahlen für ein
gegebenes Feld (i, j), i, j ∈ {0, . . . , 9}
eines Sudokus noch zur Verfügung stehen.
Dazu schliessen wir alle Zahlen aus, die in
Zeile i, in Spalte j oder dem Teilquadrat
von (i, j) schon vorkommen.
Wir speichern das Sudoku-Feld in einem
zweidimensionalen Array über den ganzen
Zahlen. Dabei habe Inhalt 0 eines Feldes
die Bedeutung “noch nicht besetzt”.
Technische Informatik für Ingenieure (TIFI)
WS 09/10
127
Beispiel: Sudoku-Spiel
6
9
¥
1
2
7
8
6
6
7
3
9
2
8
7
5
1
3
4
9
Bsp.: Für das Feld (0, 6) stehen die Zahlen
1, 2, 4, 6, 7, 8 nicht mehr zur Verfügung,
also kann das Feld (0, 6) nur mit einer der
Zahlen 3, 5 oder 9 besetzt werden.
9
3
4
9
2
8
5
Rainer Feldmann
Universität Paderborn
4
Technische Informatik für Ingenieure (TIFI)
WS 09/10
128
Problem SudokuCandidates:
geg: ein zweidimensionales , 9 × 9 int-Array A (Eintrag 0 bedeute “nicht besetzt”),
ein Feld (z, s) von A
ges: ein Array B ∈ {f alse, true}10 so daß für alle j ∈ {1, . . . , 9} gilt:
B[j] = true ⇔ j ist Kandidat für (z, s).
/* Initialisiere */
final int n = 9;
int[][] A = new int[n][n];
boolean[] B = new boolean[n+1];
/* Dimension des Sudokus */
/* reserviere Platz für n2 Arrayelemente in A */
/* reserviere Platz für n+1 Arrayelemente in B */
Out.print("A = ");
In.open("sudoku.txt");
/* lese Sudoku aus der Datei sudoku.txt */
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++) A[i][j] = In.readInt();
In.close();
/* von jetzt an lese wieder von Tastatur */
for (int j = 1; j <= n; j++) B[j] = true;
Out.print("z,s = "); int z = In.readInt(); int s = In.readInt();
/* initialisiere B */
/* lese z, s */
...
Rainer Feldmann
Universität Paderborn
Technische Informatik für Ingenieure (TIFI)
WS 09/10
129
Problem SudokuCandidates:
geg: ein zweidimensionales , 9 × 9 int-Array A (Eintrag 0 bedeute “nicht besetzt”),
ein Feld (z, s) von A
ges: ein Array B ∈ {f alse, true}10 so daß für alle j ∈ {1, . . . , 9} gilt:
B[j] = true ⇔ j ist Kandidat für (z, s).
/* Initialisiere */ ...
/* Analysiere Zeile z */
for (int j = 0; j < n; j++) { int x = A[z][j]; B[x] = false; }
/* B[A[z][j]] = false; */
/* Analysiere Spalte s */
for (int i = 0; i < n; i++) { int x = A[i][s]; B[x] = false; }
/* B[A[i][s]] = false; */
...
Rainer Feldmann
Universität Paderborn
Technische Informatik für Ingenieure (TIFI)
WS 09/10
130
Problem SudokuCandidates:
geg: ein zweidimensionales , 9 × 9 int-Array A (Eintrag 0 bedeute “nicht besetzt”),
ein Feld (z, s) von A
ges: ein Array B ∈ {f alse, true}10 so daß für alle j ∈ {1, . . . , 9} gilt:
B[j] = true ⇔ j ist Kandidat für (z, s).
/* Initialisiere */ ...
/* Analysiere Zeile z */ ...
/* Analysiere Spalte s */ ...
/* Analysiere Teilquadrat von (z, s) */
final int m = 3;
/* Größe des Teilquadrats bei n = 9 */
int p = z/m; int q = s/m;
/* (p, q) ist linke obere Ecke des Teilquadrats von (z, s) */
for (int i = p; i < p+m; i++)
for (int j = q; j < q+m; j++) { int x = A[i][j]; B[x] = false; }
...
Rainer Feldmann
Universität Paderborn
Technische Informatik für Ingenieure (TIFI)
WS 09/10
131
Problem SudokuCandidates:
geg: ein zweidimensionales , 9 × 9 int-Array A (Eintrag 0 bedeute “nicht besetzt”),
ein Feld (z, s) von A
ges: ein Array B ∈ {f alse, true}10 so daß für alle j ∈ {1, . . . , 9} gilt:
B[j] = true ⇔ j ist Kandidat für (z, s).
/*
/*
/*
/*
Initialisiere */ ...
Analysiere Zeile z */ ...
Analysiere Spalte s */ ...
Analysiere Teilquadrat von (z, s) */ ...
/* Ausgabe der Kandidaten für Feld (z, s) */
Out.print("Kandidaten(" + z + "," + s + "):");
for (int j = 1; j <= n; j++)
if (B[j]) Out.print(" "+ j);
Out.println();
Rainer Feldmann
Universität Paderborn
/* B[j] = true ⇔ j ist Kandidat */
Technische Informatik für Ingenieure (TIFI)
WS 09/10
132
Verzweigte Arrays
• Verzweigte Arrays sind Arrays, deren Elemente wieder Arrays sind.
• Im Unterschied zu mehrdimensionalen Arrays können die Arrayelemente unterschiedliche
Längen haben.
Es sei G = (V, E) ein Graph. Für einen Knoten v ∈ V
ist die Adjazenzliste A(v) definiert durch
0
1
A(v) = (w1, . . . , wk ),
(v, wi) ∈ E, 1 ≤ i ≤ k
a
3
2
Ein Graph G kann im Computer dargestellt werden, indem man seine Adjazenzlisten speichert.
1
2
3
0 1
a[0]
a[1]
a[2]
a[3]
¾
»
Adjazenzlisten benötigen bei Graphen mit wenigen Kanten
signifikant weniger Speicherplatz als die Adjazenzmatrix.
½
Rainer Feldmann
Universität Paderborn
¼
Technische Informatik für Ingenieure (TIFI)
WS 09/10
133
Beispiel: Einlesen von Adjazenzlisten eines Graphen
int n = In.readInt();
int[][] a = new int[n][];
/* lese Anzahl der Knoten von G */
/* Platz für n Adjazenzlisten */
for (int i=0; i < a.length; i++) {
Out.print("Anzahl der Nachbarn von Knoten "+i+ ": ");
int h = In.readInt();
/* lese Anzahl der Nachbarn von i */
a[i] = new int[h];
/* Platz für h Nachbarn */
for (int j = 0; j < a[i].length; j++) {
Out.print(j+". Nachbar von "+i+": ");
a[i][j] = In.readInt();
/* lese j-ten Nachbarn von i */
}
}
Rainer Feldmann
Universität Paderborn
Technische Informatik für Ingenieure (TIFI)
WS 09/10
134
Herunterladen