C++ Matrix spiralfoermig fuellen

OP (Firma: RUB) #4820605
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
Gast #4820739
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.
Gast #4821630
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren