Dies ist wirklich eine konzeptionelle (sprachunabhängige) Frage, aber um der Erklärung willen werde ich C++ verwenden. Ich würde eine Antwort bevorzugen, die in andere Sprachen portiert werden kann (keine Zeigerarithmetik oder Speichertricks).Was ist eine gute Möglichkeit, ein zweidimensionales Array zu "rotieren" (kreisförmige Verschiebung)?
Sagen wir, wir haben:
arr
, unsere rechteckigen 2D-Array von einer beliebigen ArtT
void shift(int dx, int dy)
, die Funktion, die die "Rotation"numRows
führt, die Anzahl der ReihennumCols
, die n Umbra von Spalten
shift()
verschiebt sich die Anordnung so, dass alle Zeilen dx
Plätze nach unten bewegt wird, und die Reihen geschoben außerhalb der Grenzen wird Wrap-around zum Anfang zurück. (Das gleiche gilt für die Spalten und dy
.) Lassen Sie uns sagen, das ist es, was unser Angebot wie zunächst aussieht:
{{a1, a2, a3, a4},
{b1, b2, b3, b4},
{c1, c2, c3, c4},
{d1, d2, d3, d4}};
Nachdem wir unsere Funktion aufrufen: shift(2,1)
, arr
sollte wie folgt aussehen:
{{c4, c1, c2, c3},
{d4, d1, d2, d3},
{a4, a1, a2, a3},
{b4, b1, b2, b3}};
In dieser Fall dx
war , so bewegt alles nach unten zwei Plätze und dy
war , also alles auch mov ed auf die rechts einen Platz.
war hier mein Ansatz zur Lösung dieses Problems:
void shift(int dx, int dy)
{
T newArr[numRows][numCols];
for(int r = 0; r < numRows; r++)
{
for(int c = 0; c < numCols; c++)
newArr[(r + dx) % numRows][(c + dy) % numCols] = arr[r][c];
}
for(int r = 0; r < numRows; r++)
{
for(int c = 0; c < numCols; c++)
arr[r][c] = newArr[r][c];
}
}
Ich bin nicht zufrieden mit diesem Code, weil es weder zeiteffizient noch raumeffizient ist. Ich suche eine elegantere Lösung, die mehr mit weniger Loops und weniger Speicher benötigt.
Ich verstehe nicht, warum Sie 4 for-Schleifen benötigen, um das zu lösen. Kannst du deinen Code zeigen? –
@IvanGritsenko Tut mir leid, wenn dies zu spät ist, aber ich habe meine Frage mit weiteren Details aktualisiert. –