#c
#c
Вопрос:
Я не уверен, был ли этот вопрос задан или, вполне возможно, уже дан ответ. Если я начну с исходной матрицы 3×3:
1 2 3 4 5 6 7 8 9
как бы я создал следующую матрицу 3×3:
9 6 3 8 5 2 7 4 1
??
Комментарии:
1. Вы имеете в виду транспонирование матрицы? (Если это так, то мой ответ делает это) Вы говорите, что диагональ остается неизменной, но ваш пример показывает обратное.
2. Основная диагональ — это та, которая проходит от верхнего левого угла до нижнего правого. «Отражение» вокруг главной диагонали называется транспонированием матрицы. Диагональ, о которой вы размышляете (та, которая проходит от нижнего левого угла до верхнего правого), называется антидиагональной или вторичной диагональю .
Ответ №1:
Для N * N квадратной матрицы :
for(int i=0;i<n-1;i )
for(int j=0;j<n-1-i;j ) //Swap elements above anti-diagonal
std::swap(mat[i][j],mat[n-1-j][n-1-i]); //with elements below it
Ответ №2:
Поскольку вы пытаетесь отразить вторичную диагональ (это НЕ транспозиция), вот код, слегка измененная копия кода Питера:
for (int i = 0; i < n; i )
{
for (int j = 0; j < i; j )
{
int temp = a[i][j];
a[i][j] = a[n - 1 - j][n - 1 - i];
a[n - 1 - j][n - 1 - i] = temp;
}
}
Комментарии:
1. Большое спасибо; Я переношу вторичную диагональ, потому что я создаю контрпример с числом Рамсея 13×13 R (4,4), используя компьютер, а не вручную; мне нужно было отразить это, поэтому мой алгоритм тестирования выявит плохо созданные матрицы. Спасибо!
2. Если это ответ на ваш вопрос, установите флажок рядом с ответом. Это называется «принятие ответа», и именно так мы говорим «спасибо» здесь, в StackOverflow. О, и добро пожаловать в SO.
3. Как вы вообще добираетесь до [0] в вашем коде[0]? Поскольку ‘j’ всегда должно быть меньше ‘i’, оба они никогда не могут быть равны одновременно. Правильное ограничение на ‘j’ равно j < n-1-i?
4. Это решение неверно и не должно приниматься. Что должно быть: 0 <= i < n -1, 0 <= j < n — 1 — i. Решение @Burt правильное
Ответ №3:
При отражении пары элементов в матрице меняются местами, поэтому «сделать что-нибудь» (внутри циклов) будет операцией подкачки. Циклы будут использоваться для выбора элемента для замены, и некоторые базовые арифметические действия используются для выбора того, с каким элементом его поменять. Циклы должны повторяться по треугольнику элементов, которые находятся по одну сторону от оси для отражения, исключая элементы на оси отражения и по другую ее сторону. Чтобы визуализировать это…
0 1 2
0 * * /
1 * / .
2 / . .
Звездочки — это элементы, которые будут использоваться в качестве первых параметров для подкачки. Точки — это элементы, которые будут использоваться в качестве вторых параметров для обмена. Косые черты расположены на оси отражения.
Следовательно…
for (int i = 0; i < 2; i )
{
for (int j = 0; j < (n-1)-i; j ) // Thanks to Bugaboo for bugfix
{
std::swap (a[i][j], a[2-j][2-i]);
}
}
При матрице 3×3 циклы немного избыточны — они показаны здесь для принципа и для того, чтобы показать, как его расширить. В этой визуализации всего три звездочки, и требуется всего три операции подкачки…
std::swap (a[0][0], a[2][2]);
std::swap (a[0][1], a[1][2]);
std::swap (a[1][0], a[2][1]);
Комментарии:
1. Как вы вообще добираетесь до [0] в вашем коде[0]? Поскольку ‘j’ всегда должно быть меньше ‘i’, оба они никогда не могут быть равны одновременно. Правильное ограничение на ‘j’ равно j < n-1-i
2. @Bugaboo — глупая ошибка — в моем исходном цикле было бы реализовано перемещение по главной диагонали, а не требуемое отражение по вторичной диагонали. Просматривая историю ответа, я даже сослался на чей-то другой ответ, поскольку был сбит с толку тем, какую операцию он реализует — упс.
Ответ №4:
Я думаю, что нашел способ в MatLab, который сочетает в себе ряд других существующих методов переключения.
- fliplr (переворачивать влево и вправо)
- транспонировать
- fliplr
Ham
является целевым, тогда код следующий.
Может быть, это неправильно, но дайте мне знать.
fliplr(fliplr(Ham)')