回复 17楼 鱼∞鱼
我正在考虑这个。就怕我的分到最后不够用呵呵。
重剑无锋,大巧不工
#include <stdio.h> #include <stdlib.h> #define PRECISION 0.0000000001 typedef struct node_struct { double data; int row; struct node_struct *next; }node; typedef struct handle_struct { node *right; int line; struct handle_struct *down; }handle; typedef struct matrix_struct { handle *head; int line, row; }matrix; matrix *matrix_creat(int line, int row)//创建line行row列矩阵,元素初始值为0 { matrix *tmp; if (NULL==(tmp=(matrix *)malloc(sizeof(matrix)))) return NULL; tmp->line = line; tmp->row = row; if (NULL==(tmp->head=(handle *)malloc(sizeof(handle)))) return NULL; tmp->head->right = NULL; tmp->head->down = NULL; tmp->head->line = 1; return tmp; } void print_matrix(matrix *mat) { int i = 0, j = 0; handle *tmp; node *ntmp; if (NULL==mat) return; tmp = mat->head; ntmp = tmp->right; printf("===================== your matrix ======================\n"); for (; i<mat->line; i++) { if(tmp!=NULL&&tmp->line==i+1) { ntmp = tmp->right; tmp = tmp->down; } else ntmp = NULL; for (j=0; j<mat->row; j++) { if (ntmp!=NULL&&ntmp->row==j+1) printf("%.10f ",ntmp->data),ntmp=ntmp->next; else printf("%.10f ",0); } printf("\n"); } } void matrix_free(matrix *mat)//销毁mat矩阵 { handle *current = mat->head, *tmp; node *ncrnt, *ntmp; if (NULL==mat) return; while (current!=NULL) { ncrnt = current->right; while (NULL!=ncrnt) { ntmp = ncrnt; ncrnt = ncrnt->next; free(ntmp); } tmp = current; current = current->down; free(tmp); } free(mat); } int matrix_rows_len(matrix *mat)//获取矩阵mat的行数,mat为空指针时返回0 { if (NULL==mat) return 0; return mat->line; } int matrix_cols_len(matrix *mat)//获取矩阵mat的列数,mat为空指针时返回0 { if (NULL==mat) return 0; return mat->row; } int matrix_set(matrix *mat, int line, int row, double value)//设置mat矩阵第row行第column列的元素值为value,操作成功返回0,否则返回一个非0值 { handle **target = &mat->head, *current, *tmp; node **ntrgt, *ncrnt, *ntmp; if (NULL==mat||mat->line<line||mat->row<row) return -1; while (((current=*target)!=NULL)&&(current->line<line)) target = ¤t->down; if (current!=NULL&¤t->line==line) { ntrgt = ¤t->right; while (((ncrnt=*ntrgt)!=NULL)&&(ncrnt->row<row)) ntrgt = &ncrnt->next; if (ncrnt!=NULL&&ncrnt->row==row) { if (value<PRECISION&&value>-1*PRECISION) { *ntrgt = ncrnt->next; free(ncrnt); } else ncrnt->data = value; } else { if (value<PRECISION&&value>-1*PRECISION) return 0; if (NULL==(ntmp=(node *)malloc(sizeof(node)))) return -1; ntmp->data = value; ntmp->row = row; ntmp->next = ncrnt; *ntrgt = ntmp; } } else { if (value<PRECISION&&value>-1*PRECISION) return 0; if (NULL==(tmp=(handle *)malloc(sizeof(handle)))) return -1; tmp->line = line; tmp->down = current; *target = tmp; if (NULL==(tmp->right=(node *)malloc(sizeof(node)))) return -1; tmp->right->data = value; tmp->right->row = row; tmp->right->next = NULL; } return 0; } double matrix_get(matrix *mat, int line, int row)//获取mat矩阵第line行第row列的元素值 { handle *current = mat->head; node *ncrnt; if (NULL==mat||mat->line<line||mat->row<row) return -1; while (current!=NULL&¤t->line<line) current = current->down; if (NULL!=current&¤t->line==line) { ncrnt = current->right; while (ncrnt!=NULL&&ncrnt->row<row) ncrnt = ncrnt->next; if (NULL!=ncrnt&&ncrnt->row==row) return ncrnt->data; } return 0; } matrix *matrix_add(matrix *mat1, matrix *mat2)//计算两个矩阵相加,返回和矩阵。当两个矩阵不能作加法运算时返回NULL { matrix *tmp; int i = 0, j = 0; if (mat1==NULL||mat2==NULL||mat1->line!=mat2->line||mat1->row!=mat2->row) return NULL; tmp = matrix_creat(mat1->line, mat1->row); for (; i<mat1->line; i++) for (j=0; j<mat1->row; j++) matrix_set(tmp,i+1,j+1,matrix_get(mat1,i+1,j+1) + matrix_get(mat2,i+1,j+1)); return tmp; } matrix *matrix_mul_real(matrix *mat, double a)//计算矩阵与实数相乘 { matrix *tmp; int i = 0, j = 0; if (NULL==mat) return NULL; tmp = matrix_creat(mat->line, mat->row); for (; i<mat->line; i++) for (j=0; j<mat->row; j++) matrix_set(tmp,i+1,j+1,matrix_get(mat,i+1,j+1)*a); return tmp; } matrix *matrix_mul(matrix *mat1, matrix *mat2)//计算两个矩阵相乘,注意是mat1左乘mat2。如果不能作乘法运算返回NULL { matrix *tmp; int i = 0, j = 0, k = 0; double sum = 0; if (mat1==NULL||mat2==NULL||mat1->row!=mat2->line) return NULL; tmp = matrix_creat(mat1->line, mat2->row); for (; i<mat1->line; i++) for (k=0; k<mat2->row; k++) { for (j=0; j<mat2->line; j++) sum += matrix_get(mat1,i+1,j+1)*matrix_get(mat2,j+1,k+1); matrix_set(tmp,i+1,k+1,sum); sum = 0; } return tmp; } matrix *matrix_dot_mul(matrix *mat1, matrix *mat2)//计算两个矩阵的点乘。如果不能作运算返回NULL { matrix *tmp; int i = 0, j = 0; if (mat1==NULL||mat2==NULL||mat1->row!=mat2->row||mat1->line!=mat2->line) return NULL; tmp = matrix_creat(mat1->line, mat1->row); for (; i<mat1->line; i++) for (j=0; j<mat1->row; j++) matrix_set(tmp,i+1,j+1,matrix_get(mat1,i+1,j+1)*matrix_get(mat2,i+1,j+1)); return tmp; } matrix *matrix_trans(matrix *mat)//返回mat的转置矩阵 { matrix *tmp; int i = 0, j = 0; if(NULL==mat) return NULL; tmp = matrix_creat(mat->row,mat->line); for (; i<mat->line; i++) for (j=0; j<mat->row; j++) matrix_set(tmp,j+1,i+1,matrix_get(mat,i+1,j+1)); return tmp; } void main() { matrix *mat1 = matrix_creat(6,5); matrix *mat2; matrix_set(mat1,6,1,22.5); matrix_set(mat1,5,2,3.5); matrix_set(mat1,4,4,-15.6); matrix_set(mat1,3,3,789.123); matrix_set(mat1,2,5,34.12345); matrix_set(mat1,1,5,1234.5); print_matrix(mat1); mat2 = matrix_trans(mat1); print_matrix(mat2); matrix_free(mat1); }
// sparse_matrix_one.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" ////////////////////////////////// // 结构体,宏定义及全局变量 ////////////////////////////////// #define MAX_NON_ZERO 1000 // 三元组表非零元个数的最大值 typedef int status; typedef double elem_type; typedef struct { int i, j; // 非零元的行下标和列下标 elem_type elem; // 非零元的值 }triple; typedef struct { triple data_array[MAX_NON_ZERO + 1]; // 非零三元组表,data_array[0]未用 int m_row, m_col, total; // 矩阵的行数列数 和非零元总数 }MATRIX; ////////////////////////////////// // 子函数声明 ////////////////////////////////// MATRIX * Matrix_create(int row, int column); // 创建rows行columns列矩阵,元素初始值为0 void Matrix_free(MATRIX * mat); // 销毁mat矩阵 status Matrix_rows_len(MATRIX * mat); // 获取矩阵mat的行数,mat为空指针时返回0 status Matrix_cols_len(MATRIX * mat); // 获取矩阵mat的列数,mat为空指针时返回0 status Matrix_set(MATRIX * mat, int row, int column, double value); // 设置mat矩阵第row行第column列的元素值为value, // 操作成功返回非0值,否则返回0 // 其实相当于插入操作 void Matrix_print(MATRIX *mat); // 以稀疏矩阵的形式输出 elem_type Matrix_get(MATRIX * mat, int row, // 获取mat矩阵第row行第column列的元素值 int column); MATRIX * Matrix_add(MATRIX * mat1, // 计算两个矩阵相加,返回和矩阵。当两个矩阵不 MATRIX * mat2); // 能作加法运算时返回NULL ////////////////////////////////// // 主函数入口 ////////////////////////////////// int _tmain(int argc, _TCHAR* argv[]) { MATRIX *mat1, *mat2; mat1 = Matrix_create(4, 4); mat2 = Matrix_create(4, 4); Matrix_set(mat1, 2, 3, 29); Matrix_set(mat1, 1, 4, 9); Matrix_set(mat2, 2, 4, 19); Matrix_set(mat2, 3, 2, 3); Matrix_print(mat1); Matrix_print(mat2); Matrix_add(mat1, mat2); Matrix_print(mat2); Matrix_free(mat1); Matrix_free(mat2); system("pause"); return 0; } ////////////////////////////////// // 各个子函数的具体实现 ////////////////////////////////// MATRIX * Matrix_create(int row, int column) { MATRIX *mat; mat = (MATRIX *) malloc (sizeof (MATRIX)); mat->m_col = column; mat->m_row = row; mat->total = 0; return mat; } //---------------------------------------------------------------- void Matrix_free(MATRIX * mat) { free(mat); } //---------------------------------------------------------------- status Matrix_rows_len(MATRIX * mat) { if (mat == NULL) return 0; return mat->m_row; } //---------------------------------------------------------------- status Matrix_cols_len(MATRIX * mat) { if (mat == NULL) return 0; return mat->m_col; } //---------------------------------------------------------------- status Matrix_set(MATRIX * mat, int row, int column, double value) { int point, locate; if (mat->total >= MAX_NON_ZERO) { printf("No space now!\n"); return 0; } if (mat->m_col < column || mat->m_row < row || row < 1 || column < 1) { printf("Beyond now!\n"); return 0; } // 给确定位置赋值 point = 1; if (mat->total == 0) // 矩阵初始状态为零矩阵 { mat->data_array[point].i = row; mat->data_array[point].j = column; mat->data_array[point].elem = value; mat->total++; return 1; } // 矩阵初始状态不为零 就将稀疏矩阵的确定位置赋值并放置在三元组矩阵的适当位置 for (locate = 1; locate <= mat->total; ++locate) if (row >= mat->data_array[locate].i && column >= mat->data_array[locate].j) point++; // 寻求适当的位置 if (row == mat->data_array[locate].i && column == mat->data_array[locate].j) { mat->data_array[locate].elem = value; // 如果稀疏矩阵的此位置已有非零元则将其重置 return 1; } // 移动此位置后的已有非零元 并 实施插入 for (locate = mat->total; locate >= point; locate--) { mat->data_array[locate + 1].i = mat->data_array[locate].i; mat->data_array[locate + 1].j = mat->data_array[locate].j; mat->data_array[locate + 1].elem = mat->data_array[locate].elem; } mat->data_array[point].i = row; mat->data_array[point].j = column; mat->data_array[point].elem = value; ++mat->total; return 1; } //---------------------------------------------------------------- void Matrix_print(MATRIX *mat) { int mi, mj, point = 1; if (mat->total == 0) { printf("This is a zero matrix!\n"); return ; } for (mi = 1; mi <= mat->m_row; mi++) { for (mj = 1; mj <= mat->m_col; mj++) { if (mi == mat->data_array[point].i && mj == mat->data_array[point].j) { printf("%.2f\t", mat->data_array[point].elem); point++; } else { printf("%.2f\t", 0); } } printf("\n"); } printf("\n"); } //---------------------------------------------------------------- elem_type Matrix_get(MATRIX * mat, int row, int column) { int locate; for (locate = 1; locate <= mat->total; locate++) if (mat->data_array[locate].i == row && mat->data_array[locate].j == column) return mat->data_array[locate].elem; return 0; } MATRIX * Matrix_add(MATRIX * mat1, MATRIX * mat2) { int locate1, locate2, flag = 1; triple a[MAX_NON_ZERO + 1]; int count = 1, index; if (mat1->m_col == mat2->m_col && mat1->m_row == mat2->m_row) { for (locate1 = 1; locate1 <= mat1->total; locate1++) { flag = 1; for (locate2 = 1; locate2 <= mat2->total; locate2++) if (mat1->data_array[locate1].i == mat2->data_array[locate2].i && mat1->data_array[locate1].j == mat2->data_array[locate2].j) { mat2->data_array[locate2].elem += mat1->data_array[locate1].elem; flag = 0; break; } if (flag) { a[count].i = mat1->data_array[locate1].i; a[count].j = mat1->data_array[locate1].j; a[count].elem = mat1->data_array[locate1].elem; count++; } } if (count > 1) for (index = 1; index < count; index++) { Matrix_set(mat2, a[index].i, a[index].j, a[index].elem); } return mat2; } else return 0; }调试的显示是合符我的意图的 但是为什么输出的不一样 难道真是输出函数的问题?
// sparse_matrix_one.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" ////////////////////////////////// // 结构体,宏定义及全局变量 ////////////////////////////////// #define MAX_NON_ZERO 1000 // 三元组表非零元个数的最大值 typedef int status; typedef double elem_type; typedef struct { int i, j; // 非零元的行下标和列下标 elem_type elem; // 非零元的值 }triple; typedef struct { triple data_array[MAX_NON_ZERO + 1]; // 非零三元组表,data_array[0]未用 int m_row, m_col, total; // 矩阵的行数列数 和非零元总数 }MATRIX; ////////////////////////////////// // 子函数声明 ////////////////////////////////// MATRIX * Matrix_create(int row, int column); // 创建rows行columns列矩阵,元素初始值为0 void Matrix_free(MATRIX * mat); // 销毁mat矩阵 status Matrix_rows_len(MATRIX * mat); // 获取矩阵mat的行数,mat为空指针时返回0 status Matrix_cols_len(MATRIX * mat); // 获取矩阵mat的列数,mat为空指针时返回0 status Matrix_set(MATRIX * mat, int row, int column, double value); // 设置mat矩阵第row行第column列的元素值为value, // 操作成功返回非0值,否则返回0 // 其实相当于插入操作 void Matrix_print(MATRIX *mat); // 以稀疏矩阵的形式输出 elem_type Matrix_get(MATRIX * mat, int row, // 获取mat矩阵第row行第column列的元素值 int column); MATRIX * Matrix_add(MATRIX * mat1, // 计算两个矩阵相加,返回和矩阵。当两个矩阵不 MATRIX * mat2); // 能作加法运算时返回NULL MATRIX * Matrix_trans(MATRIX * mat); // 返回mat的转置矩阵 MATRIX * Matrix_mul_real(MATRIX * mat, // 计算矩阵与实数相乘 double a); MATRIX * Matrix_dot_mul(MATRIX * mat1, //计算两个矩阵的点乘。如果不能作运算返回NULL MATRIX * mat2); MATRIX * Matrix_mul(MATRIX * mat1, // 计算两个矩阵相乘,注意是mat1左乘mat2。 MATRIX * mat2); // 如果不能作乘法运算返回NULL ////////////////////////////////// // 主函数入口 ////////////////////////////////// int _tmain(int argc, _TCHAR* argv[]) { MATRIX *mat1, *mat2, *trans; MATRIX *dot_mat, *mul; // create mat1 = Matrix_create(5, 5); mat2 = Matrix_create(5, 5); //set Matrix_set(mat1, 2, 3, 5); Matrix_set(mat1, 1, 4, 9); Matrix_set(mat1, 5, 4, 7); Matrix_set(mat2, 2, 4, 8); Matrix_set(mat2, 3, 2, 3); Matrix_set(mat2, 5, 4, 6); // print printf("Original!\n"); Matrix_print(mat1); Matrix_print(mat2); printf("Add!\n"); Matrix_add(mat1, mat2); Matrix_print(mat2); printf("Dot_mul!\n"); dot_mat = Matrix_dot_mul(mat1, mat2); Matrix_print(dot_mat); printf("Multiply!\n"); mul = Matrix_mul(mat1, mat2); Matrix_print(mul); printf("Trans!\n"); trans = Matrix_trans(mat2); Matrix_print(trans); printf("real_mul!\n"); Matrix_mul_real(mat1, 3); Matrix_print(mat1); Matrix_free(mat1); Matrix_free(mat2); Matrix_free(trans); Matrix_free(mul); system("pause"); return 0; } ////////////////////////////////// // 各个子函数的具体实现 ////////////////////////////////// MATRIX * Matrix_create(int row, int column) { MATRIX *mat; mat = (MATRIX *) malloc (sizeof (MATRIX)); mat->m_col = column; mat->m_row = row; mat->total = 0; return mat; } //---------------------------------------------------------------- void Matrix_free(MATRIX * mat) { free(mat); } //---------------------------------------------------------------- status Matrix_rows_len(MATRIX * mat) { if (mat == NULL) return 0; return mat->m_row; } //---------------------------------------------------------------- status Matrix_cols_len(MATRIX * mat) { if (mat == NULL) return 0; return mat->m_col; } //---------------------------------------------------------------- status Matrix_set(MATRIX * mat, int row, int column, double value) { int point, locate; if (mat->total >= MAX_NON_ZERO) { printf("No space now!\n"); return 0; } if (mat->m_col < column || mat->m_row < row || row < 1 || column < 1) { printf("Beyond now!\n"); return 0; } // 给确定位置赋值 point = 1; if (mat->total == 0) // 矩阵初始状态为零矩阵 { mat->data_array[point].i = row; mat->data_array[point].j = column; mat->data_array[point].elem = value; mat->total++; return 1; } // 矩阵初始状态不为零 就将稀疏矩阵的确定位置赋值并放置在三元组矩阵的适当位置 for (locate = 1; locate <= mat->total; ++locate) if (row == mat->data_array[locate].i && column >= mat->data_array[locate].j || row > mat->data_array[locate].i) point++; // 寻求适当的位置 if (row == mat->data_array[point - 1].i && column == mat->data_array[point - 1].j) { mat->data_array[point - 1].elem = value; // 如果稀疏矩阵的此位置已有非零元则将其重置 return 1; } // 移动此位置后的已有非零元 并 实施插入 for (locate = mat->total; locate >= point; locate--) { mat->data_array[locate + 1].i = mat->data_array[locate].i; mat->data_array[locate + 1].j = mat->data_array[locate].j; mat->data_array[locate + 1].elem = mat->data_array[locate].elem; } mat->data_array[point].i = row; mat->data_array[point].j = column; mat->data_array[point].elem = value; mat->total++; return 1; } //---------------------------------------------------------------- void Matrix_print(MATRIX *mat) { int mi, mj, point = 1; if (mat->total == 0) { printf("This is a zero matrix!\n"); return ; } for (mi = 1; mi <= mat->m_row; mi++) { for (mj = 1; mj <= mat->m_col; mj++) { if (mi == mat->data_array[point].i && mj == mat->data_array[point].j) { printf("%.2f\t", mat->data_array[point].elem); point++; } else { printf("%.2f\t", 0); } } printf("\n"); } printf("\n"); } //---------------------------------------------------------------- elem_type Matrix_get(MATRIX * mat, int row, int column) { int locate; for (locate = 1; locate <= mat->total; locate++) if (mat->data_array[locate].i == row && mat->data_array[locate].j == column) return mat->data_array[locate].elem; return 0; } MATRIX * Matrix_add(MATRIX * mat1, MATRIX * mat2) { int locate1, locate2, flag = 1; triple a[MAX_NON_ZERO + 1]; int count = 1, index; if (mat1->m_col == mat2->m_col && mat1->m_row == mat2->m_row) { for (locate1 = 1; locate1 <= mat1->total; locate1++) { flag = 1; for (locate2 = 1; locate2 <= mat2->total; locate2++) if (mat1->data_array[locate1].i == mat2->data_array[locate2].i && mat1->data_array[locate1].j == mat2->data_array[locate2].j) { mat2->data_array[locate2].elem += mat1->data_array[locate1].elem; flag = 0; break; } if (flag) { a[count].i = mat1->data_array[locate1].i; a[count].j = mat1->data_array[locate1].j; a[count].elem = mat1->data_array[locate1].elem; count++; } } if (count > 1) for (index = 1; index < count; index++) { Matrix_set(mat2, a[index].i, a[index].j, a[index].elem); } return mat2; } else return 0; } //---------------------------------------------------------------------- MATRIX * Matrix_trans(MATRIX * mat) { int point, col, locate; MATRIX *new_m = (MATRIX *) malloc (sizeof(MATRIX)); new_m->m_col = mat->m_col; new_m->m_row = mat->m_row; new_m->total = mat->total; if (mat->total) { point = 1; for (col = 1; col <= mat->m_col; col++) for (locate = 1; locate <= mat->total; locate++) { if (mat->data_array[locate].j == col) { new_m->data_array[point].i = mat->data_array[locate].j; new_m->data_array[point].j = mat->data_array[locate].i; new_m->data_array[point].elem = mat->data_array[locate].elem; ++point; } } } return new_m; } //--------------------------------------------------- MATRIX * Matrix_mul_real(MATRIX * mat, double a) { int point = 1; for (; point <= mat->total; point++) mat->data_array[point].elem *= a; return mat; } //------------------------------------------------------ MATRIX * Matrix_dot_mul(MATRIX * mat1, MATRIX * mat2) { int mat1_p, mat2_p; if (!(mat1->m_col == mat2->m_col && mat1->m_row == mat2->m_row)) { printf("Can not multiply!\n"); return 0; } MATRIX *new_m = Matrix_create(mat1->m_row, mat1->m_col); for (mat1_p = 1; mat1_p <= mat1->total; mat1_p++) for (mat2_p = 1; mat2_p <= mat2->total; mat2_p++) if (mat1->data_array[mat1_p].i == mat2->data_array[mat2_p].i && mat1->data_array[mat1_p].j == mat2->data_array[mat2_p].j) { Matrix_set(new_m, mat1->data_array[mat1_p].i, mat1->data_array[mat1_p].j, mat1->data_array[mat1_p].elem * mat2->data_array[mat2_p].elem); } return new_m; } //---------------------------------------------- MATRIX * Matrix_mul(MATRIX * mat1, MATRIX * mat2) { int i, j, point,locate; elem_type sum; MATRIX *new_m = Matrix_create(mat1->m_row, mat2->m_col); if(mat1->m_col != mat2->m_row) { printf("Can not multiply!\n"); return 0; } point = 1; for(i = 1; i <= new_m->m_row; i++) { for(j = 1; j <= new_m->m_col; j++) { sum = 0; for(locate = 1; locate <= mat1->m_col; locate++) { if (!Matrix_get(mat1, i, locate)) continue; if (!Matrix_get(mat2,locate, j)) continue; sum += Matrix_get(mat1, i, locate) * Matrix_get(mat2,locate, j); } if (sum != 0) { new_m->data_array[point].i = i; new_m->data_array[point].j = j; new_m->data_array[point].elem = sum; point++; new_m->total++; } } } return new_m; }