Инвертировать карту кота Арнольда - отрицательные индексы массива
Я пытаюсь реализовать карту Cat Арнольда для N*N изображений, используя следующую формулу
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
desMatrix[(i + j) % N][(i + 2 * j) % N] = srcMatrix[i][j];
}
}
Чтобы инвертировать процесс, который я делаю:
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
srcMatrix[(j-i) % N][(2*i-j) % N] = destMatrix[i][j];
}
}
Правильна ли реализация?
Мне кажется, что для определенных значений j и i я могу получить отрицательные индексы из (ji) и (2*ij); как мне справиться с этими случаями, поскольку матричные индексы только положительные?
1 ответ
В общем, когда операция по модулю (%) должна работать с отрицательными индексами, вы можете просто добавить аргумент по модулю столько раз, сколько необходимо. поскольку
x % N == ( x + a*N ) % N
для всех натуральных a, и в этом случае вы ограничены i и j в [0, N), тогда вы можете написать (N + i - j) и убедиться, что даже если i равно 0 и j равно N-1 (или даже N в этом отношении), результат всегда будет неотрицательным. К тому же, (2*N + i - 2*j) или эквивалентно (i + 2*(Nj)) всегда неотрицателен.
В этом случае, однако, это не является необходимым. Чтобы инвертировать вашу карту, вы должны повторить шаг вперед, отменив назначения. Поскольку матрица имеет унарный детерминант и сохраняет площадь, вы уверены, что в конечном итоге вы получите все свои очки (т. Е. Покрытие M(i+1) даст покрытие M(i)).
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
newMatrix[i][j] = desMatrix[(i + j) % N][(i + 2 * j) % N];
}
}
На этом этапе newMatrix и srcMatrix должны быть идентичны.
(На самом деле, вы уже запускаете обратное преобразование как прямое. Я установил обратное преобразование, которое обычно используется для прямого преобразования).