这个你还是没有说对不对
不过你没有说错,而且从你说的内容来看,应该是对的,那我就认为是对的了
#include <algorithm>
#include <iostream>
using namespace std;
void TransposeMatri(int **array, int n) { //全部转置
for(int i = 0; i < n; i++)
for(int j = 0; j < n; j++) {
if(j > i) //主副三角
swap(array[i][j], array[j][i]);
}
}
void Block_transpose(int **array, int n) { //分块转置
int k = 2;
for(int i = 0; i < n; i += k)
for(int j = 0; j < n; j += k)
TransposeMatri((int **)((int *)array + i * n + j), k);
}
int main() {
int **a = new int *[4];
for(int i = 0; i < 4; i++)
a[i] = new int[4];
for(int i = 0; i < 4; i++) {
for(int j = 0; j < 4; j++) {
a[i][j] = i * 4 + j;
}
}
for(int i = 0; i < 4; i++) {
for(int j = 0; j < 4; j++)
cout << a[i][j] << ' ';
cout << endl;
}
Block_transpose(a, 4);
cout << "---------------------" << endl;
/*
for(int i = 0; i < 4; i++)
for(int j = 0; j < 4; j++)
cout << a[i][j] << ' ';
cout << endl;
*/
for(int i = 0; i < 4; i++) {
for(int j = 0; j < 4; j++)
cout << a[i][j] << ' ';
cout << endl;
}
// 释放一定要写,不写释放的代码在一些环境下会报错的
for(int i = 0; i < 4; i++)
delete[] a[i];
delete[] a;
return 0;
}
这个代码是错的,因为你进行了强制类型转换,可以通过编译了,但是类型不对
地址值是一样的,但是类型不对
应该转成下面这样
#include <algorithm>
#include <iostream>
using namespace std;
void TransposeMatri(int **array, int n) { //全部转置
for(int i = 0; i < n; i++)
for(int j = 0; j < n; j++) {
if(j > i) //主副三角
//swap(array[i][j], array[j][i]);
swap((*(int (*)[n][n])(array))[i][j], (*(int (*)[n][n])(array))[j][i]);
}
}
void Block_transpose(int **array, int n) { //分块转置
int k = 2;
for(int i = 0; i < n; i += k)
for(int j = 0; j < n; j += k)
TransposeMatri((int **)((int *)array + i * n + j), k);
}
int main() {
int **a = new int *[4];
for(int i = 0; i < 4; i++)
a[i] = new int[4];
for(int i = 0; i < 4; i++) {
for(int j = 0; j < 4; j++) {
a[i][j] = i * 4 + j;
}
}
for(int i = 0; i < 4; i++) {
for(int j = 0; j < 4; j++)
cout << a[i][j] << ' ';
cout << endl;
}
Block_transpose(a, 4);
cout << "---------------------" << endl;
/*
for(int i = 0; i < 4; i++)
for(int j = 0; j < 4; j++)
cout << a[i][j] << ' ';
cout << endl;
*/
for(int i = 0; i < 4; i++) {
for(int j = 0; j < 4; j++)
cout << a[i][j] << ' ';
cout << endl;
}
// 释放一定要写,不写释放的代码在一些环境下会报错的
for(int i = 0; i < 4; i++)
delete[] a[i];
delete[] a;
return 0;
}
TransposeMatri((int **)((int *)array + i * n + j), k);
我一开始确实是在这里改的,但是我发现这里修改对 int a[4][4];,这样的数组无效,所以修改了swap((*(int (*)[n][n])(array))[i][j], (*(int (*)[n][n])(array))[j][i]);
但是这样依然不对,因为这样的转换要求数组中的值是连续存放的,通过 new 这样的形式创建出来的数组,数组中存储的值不是连续的
#include <algorithm>
#include <iostream>
using namespace std;
void TransposeMatri(int **array, int n) { //全部转置
for(int i = 0; i < n; i++)
for(int j = 0; j < n; j++) {
if(j > i) //主副三角
//swap(array[i][j], array[j][i]);
swap((*(int (*)[n][n])(array))[i][j], (*(int (*)[n][n])(array))[j][i]);
}
}
void Block_transpose(int **array, int n) { //分块转置
int k = 2;
for(int i = 0; i < n; i += k)
for(int j = 0; j < n; j += k)
TransposeMatri((int **)((int *)array + i * n + j), k);
}
int main() {
/*
int **a = new int *[4];
for(int i = 0; i < 4; i++)
a[i] = new int[4];
*/
int a[4][4];
for(int i = 0; i < 4; i++) {
for(int j = 0; j < 4; j++) {
a[i][j] = i * 4 + j;
}
}
for(int i = 0; i < 4; i++) {
for(int j = 0; j < 4; j++)
cout << a[i][j] << ' ';
cout << endl;
}
//Block_transpose(a, 4);
Block_transpose((int **)a, 4);
cout << "---------------------" << endl;
/*
for(int i = 0; i < 4; i++)
for(int j = 0; j < 4; j++)
cout << a[i][j] << ' ';
cout << endl;
*/
for(int i = 0; i < 4; i++) {
for(int j = 0; j < 4; j++)
cout << a[i][j] << ' ';
cout << endl;
}
/*
// 释放一定要写,不写释放的代码在一些环境下会报错的
for(int i = 0; i < 4; i++)
delete[] a[i];
delete[] a;
*/
return 0;
}
$ ./main
0 1 2 3
4 5 6 7
8 9 10 11
12 13 14 15
---------------------
0 2 1 4
3 5 6 7
8 10 9 12
11 13 14 15
$
这样就能运行了,不会在运行的时候报错,然后停止运行了
但是结果依然不对
因为这个数组在内存中是这样存储的
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
是线性的,0 后面存储 1,1 后面存储 2,2 后面存储 3,。。。
第一个子矩阵中,你要互换的是 1 和 4,但是 1 和 4 并不挨着
要么进行计算,算出 4 的地址,要么创建一个临时数组,让 1 和 4 挨着
我选择了后者#include <algorithm>
#include <iostream>
using namespace std;
void TransposeMatri(int **array, int n) { //全部转置
for(int i = 0; i < n; i++)
for(int j = 0; j < n; j++) {
if(j > i) //主副三角
//swap(array[i][j], array[j][i]);
swap((*(int (*)[n][n])(array))[i][j], (*(int (*)[n][n])(array))[j][i]);
}
}
void Block_transpose(int **array, int n) { //分块转置
/*
int k = 2;
for(int i = 0; i < n; i += k)
for(int j = 0; j < n; j += k)
TransposeMatri((int **)((int *)array + i * n + j), k);
*/
int k = 2;
for(int i = 0; i < n; i += k)
for(int j = 0; j < n; j += k) {
int a[k][k];
for(int y = 0; y < k; ++y) {
for(int x = 0; x < k; ++x) {
a[y][x] = (*(int (*)[n][n])array)[i + y][j + x];
}
}
//TransposeMatri((int **)((int *)array + i * n + j), k);
TransposeMatri((int **)a, k);
for(int y = 0; y < k; ++y) {
for(int x = 0; x < k; ++x) {
(*(int (*)[n][n])array)[i + y][j + x] = a[y][x];
}
}
}
}
int main() {
/*
int **a = new int *[4];
for(int i = 0; i < 4; i++)
a[i] = new int[4];
*/
int a[4][4];
for(int i = 0; i < 4; i++) {
for(int j = 0; j < 4; j++) {
a[i][j] = i * 4 + j;
}
}
for(int i = 0; i < 4; i++) {
for(int j = 0; j < 4; j++)
cout << a[i][j] << ' ';
cout << endl;
}
//Block_transpose(a, 4);
Block_transpose((int **)a, 4);
cout << "---------------------" << endl;
/*
for(int i = 0; i < 4; i++)
for(int j = 0; j < 4; j++)
cout << a[i][j] << ' ';
cout << endl;
*/
for(int i = 0; i < 4; i++) {
for(int j = 0; j < 4; j++)
cout << a[i][j] << ' ';
cout << endl;
}
/*
// 释放一定要写,不写释放的代码在一些环境下会报错的
for(int i = 0; i < 4; i++)
delete[] a[i];
delete[] a;
*/
return 0;
}
$ ./main
0 1 2 3
4 5 6 7
8 9 10 11
12 13 14 15
---------------------
0 4 2 6
1 5 3 7
8 12 10 14
9 13 11 15
$
a[y][x] = (*(int (*)[n][n])array)[i + y][j + x];
其实这样也需要计算 4 的地址,然后读取 4 的值到 临时数组
我认为创建临时数组比较好,所以选择了创建临时数组
|