根据Strassen矩阵乘法的分治思想,用C++实现两个矩阵的乘法,要求如下: 1) 输入矩阵维数m和n; 2) 自动生成两个矩阵的元素(为正整数),输出保存到文件matriaA.txt和matriaB.txt。
时间: 2024-05-02 16:18:35 浏览: 125
3)从文件matriaA.txt和matriaB.txt中读入两个矩阵; 4)计算两个矩阵的乘积,并输出结果保存到文件matriaC.txt。
以下是代码实现:
```c
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void generate_matrix(int m, int n, char* filename) {
FILE* fp = fopen(filename, "w");
srand(time(NULL)); //设置随机种子
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
int num = rand() % 10 + 1; //生成1~10的随机数
fprintf(fp, "%d ", num);
}
fprintf(fp, "\n");
}
fclose(fp);
}
void read_matrix(int m, int n, char* filename, int matrix[m][n]) {
FILE* fp = fopen(filename, "r");
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
fscanf(fp, "%d", &matrix[i][j]);
}
}
fclose(fp);
}
void write_matrix(int m, int n, char* filename, int matrix[m][n]) {
FILE* fp = fopen(filename, "w");
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
fprintf(fp, "%d ", matrix[i][j]);
}
fprintf(fp, "\n");
}
fclose(fp);
}
void strassen(int m, int n, int A[m][n], int B[m][n], int C[m][n]) {
if (m == 1 && n == 1) {
C[0][0] = A[0][0] * B[0][0];
return;
}
int p = m / 2, q = n / 2;
int A11[p][q], A12[p][q], A21[p][q], A22[p][q];
int B11[p][q], B12[p][q], B21[p][q], B22[p][q];
int C11[p][q], C12[p][q], C21[p][q], C22[p][q];
int P1[p][q], P2[p][q], P3[p][q], P4[p][q], P5[p][q], P6[p][q], P7[p][q];
//将矩阵A和B分成四个子矩阵
for (int i = 0; i < p; i++) {
for (int j = 0; j < q; j++) {
A11[i][j] = A[i][j];
A12[i][j] = A[i][j + q];
A21[i][j] = A[i + p][j];
A22[i][j] = A[i + p][j + q];
B11[i][j] = B[i][j];
B12[i][j] = B[i][j + q];
B21[i][j] = B[i + p][j];
B22[i][j] = B[i + p][j + q];
}
}
//计算七个矩阵乘积
strassen(p, q, A11, B11, P1);
strassen(p, q, A12, B21, P2);
strassen(p, q, A11, B12, P3);
strassen(p, q, A12, B22, P4);
strassen(p, q, A21, B11, P5);
strassen(p, q, A22, B21, P6);
strassen(p, q, A21, B12, P7);
//计算C11~C22
for (int i = 0; i < p; i++) {
for (int j = 0; j < q; j++) {
C11[i][j] = P1[i][j] + P2[i][j];
C12[i][j] = P3[i][j] + P4[i][j];
C21[i][j] = P5[i][j] + P6[i][j];
C22[i][j] = P7[i][j] - P2[i][j] + P4[i][j] + P6[i][j];
}
}
//将C11~C22合并成C
for (int i = 0; i < p; i++) {
for (int j = 0; j < q; j++) {
C[i][j] = C11[i][j];
C[i][j + q] = C12[i][j];
C[i + p][j] = C21[i][j];
C[i + p][j + q] = C22[i][j];
}
}
}
int main() {
int m, n;
printf("Please input the dimension of matrix (m,n): ");
scanf("%d,%d", &m, &n);
int A[m][n], B[m][n], C[m][n];
generate_matrix(m, n, "matriaA.txt");
generate_matrix(m, n, "matriaB.txt");
read_matrix(m, n, "matriaA.txt", A);
read_matrix(m, n, "matriaB.txt", B);
strassen(m, n, A, B, C);
write_matrix(m, n, "matriaC.txt", C);
printf("The result has been saved to file matriaC.txt.\n");
return 0;
}
```
注意事项:
- 代码中使用了递归函数,递归深度可能很大,如果数据规模很大,应该使用非递归的实现方式;
- 代码中使用了动态数组,如果使用静态数组,需要在函数参数中将数组大小明确指定;
- 代码中使用了文件读写操作,需要确认文件是否存在以及文件读写操作是否成功。
阅读全文