Forum: PC-Programmierung C++ Matrix spiralfoermig fuellen


von Kaj G. (Firma: RUB) (bloody)


Lesenswert?

Nabend Leute :)

In der Vorlesung Informatik 1 gabs folgende Hausaufgabe:
1
Ergänzen Sie das folgende C++-Programmfragment so, dass bei
2
Ausführung die Zahlen 1, 2, 3 ... n*n in das zweidimensionale
3
Array matrix[n][n] als Spirale im Uhrzeigersinn geschrieben
4
werden. Z.B. wollen wir für n=4 die folgende Ausgabe haben:
5
 1  2  3  4
6
12 13 14  5
7
11 16 15  6
8
10  9  8  7

Das Codefragemnt dazu:
1
#include <iostream>
2
using namespace std;
3
4
int main () {
5
    const unsigned int n = 5;
6
    unsigned int matrix[n][n];
7
8
    //*************************************
9
    // Hier beliebig viele Zeilen ergaenzen
10
    //*************************************
11
12
    for (unsigned int r = 0; r < n; ++r){
13
        for (unsigned int c = 0; c < n; ++c){
14
            if (matrix [r][c] < 10){
15
                cout << ' ';
16
            }
17
            cout << matrix[r][c] << ' ';
18
        }
19
        cout << endl;
20
    }
21
22
    return 0;
23
}

An dem bestehenden Codefragment (also den beiden for-Schleifen) soll 
natuerlich nichts geaendert werden.

Meine Loesung fuer diese Aufgabe sieht so aus:
1
#include <iostream>
2
using namespace std;
3
4
int main () {
5
    const unsigned int n = 5;
6
    unsigned int matrix[n][n];
7
8
    //*************************************
9
    // Hier beliebig viele Zeilen ergaenzen
10
11
    int counter = 1, x = 0, y = n - 1;
12
13
    while (counter <= (n * n)) {
14
        //  von links nach rechts
15
        for (int i = x; i <= y; i++) {
16
            matrix[x][i] = counter++;
17
        }
18
19
        //  von oben nach unten
20
        for (int i = x + 1; i <= y; i++) {
21
            matrix[i][y] = counter++;
22
        }
23
24
        //  von rechts wieder nach links
25
        for (int i = y - 1; i >= x; i--) {
26
            matrix[y][i] = counter++;
27
        }
28
        y--;
29
30
        //  von unten wieder nach oben
31
        for (int i = y; i > x; i--) {
32
            matrix[i][x] = counter++;
33
        }
34
        x++;
35
    }
36
37
    //*************************************
38
39
    for (unsigned int r = 0; r < n; ++r){
40
        for (unsigned int c = 0; c < n; ++c){
41
            if (matrix [r][c] < 10){
42
                cout << ' ';
43
            }
44
            cout << matrix[r][c] << ' ';
45
        }
46
        cout << endl;
47
    }
48
49
    return 0;
50
}

Meine Loesung (scheint) fuer beliebige n-Werte (solange n >= 1) zu 
funktionieren.

Meine Frage:
Wie haettet Ihr das gemacht? Kann man das so stehen lassen, oder habt 
Ihr noch ein paar Tipps wie man das haette besser machen koennen?

Freue mich ueber euren Input :)

Gruesse

von Flitzenpiep (Gast)


Lesenswert?

Kaj G. schrieb:
> wie man das haette besser machen koennen?

Na ja, "besser", keine Ahnung. Ich habe es mal mit zwei Schleifen 
versucht; es geht sicher auch eleganter. Sollte aber funktionieren, 
denke ich.

1
int a = n;
2
int dir = 1;
3
int idx = 0;
4
int x = 0;
5
int y = -1;
6
do
7
{
8
  int *v = &y;
9
  for (int i = 0; i < 2 * a - 1; i++)
10
  {
11
    if (i == a) v = &x;
12
    *v += dir;
13
    matrix[x][y] = idx;
14
    idx++;
15
  };
16
17
  a--;
18
  dir *= -1;
19
20
} while (a > 0);

oder einfach

1
for (int i = 0; i < 2 * a - 1; i++)
2
{
3
  if (i < a)
4
    y += direction;
5
  else
6
    x += direction;
7
  ...

oder mit zwei separaten inneren Schleifen ("horizontal/vertikal").

> Wie haettet Ihr das gemacht?

Bei Prüfungen, Hausaufgaben & Co. so einfach wie noch gerade nicht 
peinlich und auch mit einem Kater problemlos erklärbar.

von Thomas (Gast)


Lesenswert?

Mein Lesbarkeitsfavorit wäre es, die Grenzen des leeren Bereichs 
explizit mitzuführen:
1
  // aktuell zu fuellender zeilenbereich. inklusive
2
  int min_r = 0;
3
  int max_r = n-1;
4
5
  // aktuell zu fuellender spaltenbereich. inklusive
6
  int min_c = 0;
7
  int max_c = n-1;
8
9
  int cnt = 0;
10
  while (min_r <= max_r && min_c <= max_c)
11
  {
12
    //oberste reihe r = min_r
13
    for (int c = min_c; c <= max_c; ++c)
14
      matrix[min_r][c] = cnt++;
15
    ++min_r; // obere reihe fertig, ausschliessen
16
    
17
    //rechte spalte c = max_c
18
    for (int r = min_r; r <= max_r; ++r )
19
      matrix[r][max_c] = cnt++;
20
    --max_c; // rechte spalte fertig, ausschliessen
21
22
    //unterste reihe r = max_r
23
    for (int c = max_c; c >= min_c; --c)
24
      matrix[max_r][c] = cnt++;
25
    --max_r; // obere reihe fertig, ausschliessen
26
27
    //linke spalte c = min_c
28
    for (int r = max_r; r >= min_r; --r )
29
      matrix[r][min_c] = cnt++;
30
    ++min_c; // linke spalte fertig, ausschliessen
31
  }
Das hat die nette Nebenwirkung, dass es auch mit rechteckigen Matrizen 
funktioniert.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.