二维数组各列最大值求解及求和代码故障排查
我需要实现找出N×N二维浮点数组中每列的最大值,并计算这些最大值的总和。编写C++代码后,初始化数组并打印输出,再求解各列最大值,但部分测试用例运行异常:
测试用例1(运行正常)
[5.7 ; 4.2 ; 5.8;]
[654.87; 5.86; 3.76;]
[8.54; 7.54; 8.4;]第1列最大值 = A[2,1] = 654.87;
第2列最大值 = A[3,2] = 7.54;
第3列最大值 = A[3,3] = 8.4;
测试用例2(运行异常)
[4.6 ; 2.65 ; 76.3;]
[65.64; 7.32; 76.2;]
[654.8; 1.6; 5.7;]第1列最大值 = A[3,1] = 654.8;
第2列最大值 = A[3,2] = 7.32;
第3列最大值 = A[3,3] = 5.7;
需要排查的代码如下:
#include<iostream> #include<conio.h> int main(void) { system("cls"); int N; int suma = 0; A: std::cout<<"Write array size N x N : "; std::cin>>N; if(N>10 || N<=1) { system("cls"); std::cout<<"N must be <= 10 and > 1;"<<std::endl; goto A; } float **A = new float *[N]; for(int i = 0; i < N; i++) { A[i] = new float [N]; for(int j = 0; j < N; j++) { std::cout<<"A["<<i+1<<"]["; std::cout<<j+1<<"] = "; std::cin>>(*(*(A+i)+j)); } } system("cls"); for(int i = 0; i < N; i++) { for(int j = 0; j < N; j++) { if(j<N-1) { std::cout<<"A["<<i+1<<"]["<<j+1<<"] = "<<*(*(A+i)+j); std::cout<<"; "; } else { std::cout<<"A["<<i+1<<"]["<<j+1<<"] = "<<*(*(A+i)+j); std::cout<<";"<<std::endl; } } } float *max = new float [N]; std::cout<<"------------------------------------"; std::cout<<std::endl; for(int i = 0; i < N - (N - 1); i++) { for(int j = 0; j < N; j++) { *(max+j) = *(*(A+i)+j); } } for(int i = 0; i < N; i++) { for(int j = 0; j < N; j++) { if( (*(max+i)) < (*(*(A+j))+i) && (*(max+i)) != ((*(*(A+j)))+i) ) { *(max+i) = *(*(A+j)+i); } } } for(int i = 0; i < N; i++) { for(int j = 0; j < N; j++) { if( (*(*(A+j)+i)) == (*(max+i)) ) { std::cout<<"Max value of "<<i+1; std::cout<<" column = "; std::cout<<"A["<<j+1<<"]["<<i+1; std::cout<<"] = "<<(*(max+i)); std::cout<<std::endl; } } suma+=(*(max+i)); } std::cout<<"Sum of largest value = "<<suma; _getch(); }
代码问题分析
最大值数组初始化逻辑错误
初始化max数组的循环条件i < N - (N - 1)等价于i < 1,只会将数组第一行的元素赋值给max,但正确逻辑应该是对每一列,先把该列的第一个元素作为初始最大值。数组元素访问语法错误
比较逻辑中的*(*(A+j))+i是错误写法,它会取A[j][0]的值再加i,而非访问A[j][i],正确写法应为*(*(A+j)+i)或更易读的A[j][i]。冗余且错误的条件判断
比较条件中的(*(max+i)) != ((*(*(A+j)))+i)完全多余,且因语法错误导致逻辑混乱,找最大值只需判断当前元素是否大于记录的最大值即可。重复输出问题
输出最大值时会遍历列中所有元素,只要等于最大值就输出,若列中有多个相同最大值会重复输出,不符合需求。变量类型错误
suma被定义为int类型,但存储的是浮点型总和,会导致精度丢失,应改为float或double。内存泄漏
代码中用new分配了二维数组A和一维数组max,但无对应的delete操作,会造成内存泄漏。
修正后的代码
#include<iostream> #include<conio.h> int main(void) { system("cls"); int N; float suma = 0; // 修正为浮点型,避免精度丢失 A: std::cout<<"输入数组大小 N x N : "; std::cin>>N; if(N>10 || N<=1) { system("cls"); std::cout<<"N 必须满足 <=10 且 >1;"<<std::endl; goto A; } // 分配二维数组 float **A = new float *[N]; for(int i = 0; i < N; i++) { A[i] = new float [N]; for(int j = 0; j < N; j++) { std::cout<<"A["<<i+1<<"]["<<j+1<<"] = "; std::cin>>A[i][j]; // 使用下标访问,提升可读性 } } system("cls"); // 打印数组 for(int i = 0; i < N; i++) { for(int j = 0; j < N; j++) { std::cout<<"A["<<i+1<<"]["<<j+1<<"] = "<<A[i][j]; j < N-1 ? std::cout<<"; " : std::cout<<";"<<std::endl; } } float *max = new float [N]; std::cout<<"------------------------------------"<<std::endl; // 初始化每列最大值为该列第一个元素 for(int i = 0; i < N; i++) { max[i] = A[0][i]; } // 遍历每一列找最大值 for(int col = 0; col < N; col++) { for(int row = 1; row < N; row++) { if(max[col] < A[row][col]) { max[col] = A[row][col]; } } } // 输出每列最大值并计算总和 for(int col = 0; col < N; col++) { // 找到最大值所在的第一行 int rowIndex = 0; for(int row = 0; row < N; row++) { if(A[row][col] == max[col]) { rowIndex = row; break; } } std::cout<<"第"<<col+1<<"列最大值 = A["<<rowIndex+1<<"]["<<col+1<<"] = "<<max[col]<<";"<<std::endl; suma += max[col]; } std::cout<<"最大值总和 = "<<suma<<std::endl; // 释放内存,避免泄漏 for(int i = 0; i < N; i++) { delete[] A[i]; } delete[] A; delete[] max; _getch(); return 0; }
内容的提问来源于stack exchange,提问作者Speak Dony

