给定两个矩阵A和B,求其和矩阵C=A+B。
输入格式:
第一行包含两个数Row和Col,分别表示矩阵的行数和列数,A和B的维度是一致的。
第二行只有一个数N1,表示接下来要输入的A中的非零元素的个数。
接下来是N1行,每一行都是i j A[i,j] 这样的形式,表示的A中第i行第j列的元素A[i,j],为了与大多数编程语言保持一致,它们都是从零开始的,也就是说下标的有效范围是[0,Row−1]×[0,Col−1]。
在N1行之后,是一个数N2,表示矩阵B中非零元素的数量,此后N2行描述B中的非零元素,它们与此前描述A中非零元素的形式一致。
矩阵元素的输入均遵循行主序。这里的所有的输入均可用int
类型正确表示,可以假设输入均是合法的。
输出格式:
第一行输出和矩阵C=A+B中的绝对值大于0.1的元素个数N3,此后是N3行,按照行主序输出其中的非零元素,依次是行、列的下标和对应的元素。
输入样例:
2 2
1
1 1 1
1
0 0 1
输出样例:
2
0 0 1
1 1 1
思路分析:
这道题思路比较清晰,奈何我猪脑过载, 迭代了好几个版本,最后回到了开始的地方才过,文章末尾将附上每次版本的代码。下面是写该题时写的草稿。
输入创建三元组,可参看:数据结构 三元组、矩阵、广义表 学习心得代码,(在主函数与CreateTS函数中实现)。CreateTS函数略有修改,以及主函数代码见后文。
就最后一次提交成功的代码来说,Add的函数中,直接先尝试col*row时间复杂度的计算算法,从0,0开始遍历,如果TS1中序号为No1的元素i和j和本次循环(即此次遍历的行和列)相同,则判断TS2中有无,若TS2中没有的话,直接将TS1的No1的元素写入结果三元组TS3;若TS2中有,则两元素中的内容相加,写入TS3。前面已经判断完TS1,直接判断TS2中序号No2的元素i和j与循环的i,j是否相同即可。要注意判断成功后No1++,No2++,以及写入TS3的元素判断绝对值大于0.1(非零)后的No3++。(大意可见图解)
最后该二重循环结束之后的No3就是结果三元组的非零个数,直接打印或者返回即可。之后直接调用打印三元组内容的函数(PrintTS),得到输出结果。
代码展示:
//
// Created by DDD on 2023/11/6.
//
#include <stdio.h>
#define MAXSIZE 80
typedef struct {
int i,j;
int e;
}Tuple;
typedef struct {
Tuple data[MAXSIZE];
int nZeros;
}TSMatrix;
void CreateTS(TSMatrix *TS, int NotZ){ //创建三元组
TS->nZeros = NotZ;
for(int i = 0;i<NotZ;i++){
scanf("%d %d %d",&TS->data[i].i,&TS->data[i].j,&TS->data[i].e);
}
}
void PrintTS(TSMatrix *ts){ //打印三元组矩阵
for (int i = 0; i < ts->nZeros; ++i) {
printf("%d %d %d\n",ts->data[i].i,ts->data[i].j,ts->data[i].e);
}
}
void Add(TSMatrix *A, TSMatrix *B, TSMatrix *C, int row, int col){
int No1 = 0, No2 = 0 ,No3= 0;
for(int i = 0; i < row; i++){
for (int j = 0; j < col; ++j) {
if(A->data[No1].i != i && B->data[No2].i != i)
break;
if(A->data[No1].i == i && A->data[No1].j == j){
if(B->data[No2].i == i && B->data[No2].j == j){
C->data[No3].i = i;
C->data[No3].j = j;
C->data[No3].e = A->data[No1].e + B->data[No2].e;
No1++;
No2++;
if(C->data[No3].e != 0) {
No3++;
}
}
else{
C->data[No3].i = i;
C->data[No3].j = j;
C->data[No3].e = A->data[No1].e;
No1++;
No3++;
}
}
if(B->data[No2].i == i && B->data[No2].j == j){
C->data[No3].i = i;
C->data[No3].j = j;
C->data[No3].e = B->data[No2].e;
No2++;
No3++;
}
}
}
C->nZeros = No3;
}
int main(){
int row,col;
scanf("%d %d",&row,&col);
int nZ1,nZ2;
TSMatrix TS1,TS2,Sum;
scanf("%d",&nZ1);
CreateTS(&TS1,nZ1);
scanf("%d",&nZ2);
CreateTS(&TS2,nZ2);
CreateTS(&Sum,0);
Add(&TS1, &TS2, &Sum, row, col);
printf("%d\n",Sum.nZeros);
PrintTS(&Sum);
}
几次失败的代码:
1. 思路不算太清晰,只能过第一个和第四个检测点:(Add函数思路不清,通过的终版是基于此版改出来的)
//
// Created by DDD on 2023/11/6.
//
#include <stdio.h>
#define MAXSIZE 80
typedef struct {
int i,j;
int e;
}Tuple;
typedef struct {
Tuple data[MAXSIZE];
int rows,cols,nZeros;
}TSMatrix;
void CreateTS(TSMatrix *TS, int row, int col, int NotZ){ //创建三元组
TS->rows = row;
TS->cols = col;
TS->nZeros = NotZ;
for(int i = 0;i<NotZ;i++){
scanf("%d %d %d",&TS->data[i].i,&TS->data[i].j,&TS->data[i].e);
}
}
void PrintTS(TSMatrix *ts){ //打印三元组矩阵
for (int i = 0; i < ts->nZeros; ++i) {
printf("%d %d %d\n",ts->data[i].i,ts->data[i].j,ts->data[i].e);
}
}
void Add(TSMatrix *A, TSMatrix *B, TSMatrix *C, int row){
int No1 = 0, No2 = 0 ,No3= 0;
for(int i = 0; i < row; i++){
while (1) {
if (A->data[No1].i == i && No1 < A->nZeros){
if(A->data[No1].j == B->data[No2].j){
C->data[No3].i = i;
C->data[No3].j = A->data[No1].j;
C->data[No3].e = A->data[No1].e + B->data[No2].e;
No1++;
No2++;
if(C->data[No3].e != 0) {
No3++;
C->nZeros++;
}
continue;
} else {
C->data[No3].i = A->data[No1].i;
C->data[No3].j = A->data[No1].j;
C->data[No3].e = A->data[No1].e;
No3++;
No1++;
C->nZeros++;
}
}
else if(B->data[No2].i == i && No2 < B->nZeros){
if(A->data[No1].j == B->data[No2].j){
C->data[No3].i = i;
C->data[No3].j = A->data[No1].j;
C->data[No3].e = A->data[No1].e + B->data[No2].e;
No1++;
No2++;
if(C->data[No3].e != 0) {
No3++;
C->nZeros++;
}
continue;
}
else {
C->data[No3].i = B->data[No2].i;
C->data[No3].j = B->data[No2].j;
C->data[No3].e = B->data[No2].e;
No3++;
No2++;
C->nZeros++;
}
}
else break;
}
}
}
int main(){
int row,col;
scanf("%d %d",&row,&col);
int nZ1,nZ2;
TSMatrix TS1,TS2,Sum;
scanf("%d",&nZ1);
CreateTS(&TS1,row,col,nZ1);
scanf("%d",&nZ2);
CreateTS(&TS2,row,col,nZ2);
CreateTS(&Sum,row,col,0);
Add(&TS1, &TS2, &Sum, row);
//PrintTS(&TS1);
//PrintTS(&TS2);
printf("%d\n",Sum.nZeros);
PrintTS(&Sum);
}
2. 将三元组在进行加法之前,先转化成二维数组储存形式,加完之后再换回来(费时):只能通过第一个测试点,其他的会报段错误,三元组和二维数组互相转化的代码可见:http://t.csdnimg.cn/OVL8J
//
// Created by DDD on 2023/11/7.
//
#include <stdio.h>
#define MAXSIZE 1000
typedef struct {
int i,j;
int e;
}Tuple;
typedef struct {
Tuple data[MAXSIZE];
int nZeros;
}TSMatrix;
int main(){
int row,col;
scanf("%d %d",&row,&col);
TSMatrix TS1;
TSMatrix TS2;
TSMatrix Sum;
scanf("%d",&TS1.nZeros);
for(int i = 0;i<TS1.nZeros;i++){
scanf("%d %d %d",&TS1.data[i].i,&TS1.data[i].j,&TS1.data[i].e);
}
scanf("%d",&TS2.nZeros);
for(int i = 0;i<TS2.nZeros;i++){
scanf("%d %d %d",&TS2.data[i].i,&TS2.data[i].j,&TS2.data[i].e);
}
int arr1[row][col];
int arr2[row][col];
int arr3[row][col];
for(int i = 0;i<row;i++) {
for (int j = 0; j < col; ++j) {
arr1[i][j] = 0;
arr2[i][j] = 0;
}
}
for(int i = 0; i<TS1.nZeros;i++){
arr1[TS1.data[i].i][TS1.data[i].j] = TS1.data[i].e;
}
for (int i = 0; i < TS2.nZeros; ++i) {
arr2[TS2.data[i].i][TS2.data[i].j] = TS2.data[i].e;
}
for(int i = 0;i<row;i++) {
for (int j = 0; j < col; ++j) {
arr3[i][j] = arr1[i][j] + arr2[i][j];
}
}
int nz = 0;
for(int i = 0;i<row;i++) {
for (int j = 0; j < col; j++) {
if(arr3[i][j] != 0){
Sum.data[nz].i = i;
Sum.data[nz].j = j;
Sum.data[nz].e = arr3[i][j];
nz++;
}
}
}
Sum.nZeros = nz;
printf("%d\n",nz);
for (int i = 0; i < Sum.nZeros; ++i) {
printf("%d %d %d\n",Sum.data[i].i,Sum.data[i].j,Sum.data[i].e);
}
}
3. 由于前面段错误,所以第三版考虑打算考虑链表,但是由于个人原因,还是转战了就两个报错的第一版。
此章毕