C++矩阵每行唯一元素统计程序的错误修正问询
问题:修正C++矩阵行唯一元素统计程序
需求说明
编写C++程序统计MxN矩阵每行的唯一元素数量,输入输出示例如下:
| 输入 | 输出 |
|---|---|
| M=3,N=4 | - |
| 1|2|2|1 | row-1:2 |
| 1|2|3|4 | row-2:2 |
现有代码
#include <iostream> using namespace std; int main() { int M,N; cin>>M>>N; int a[M][N]; for(int i=1;i<=M; i++){ for(int j=1;j<=N;j++){ cin>>a[i][j]; } } for(int i=1;i<=M;i++){ int count=1; for(int j=1;j<N;j++){ if(a[i][j]==a[i][j+1]) continue; else count++; } cout<<"row-"<<i<<":"<<count; } }
问题现象
- 输入行
{1,2,2,1}时,程序输出3,不符合预期的2; - 若将count初始化为0,输入行
{1,2,3,4}时程序输出4,也不符合预期的2。
修正方案及解释
核心问题分析
原代码的逻辑是统计相邻不同元素的次数+1,仅适用于元素连续重复的场景(比如1,1,2,2会得到正确结果2),但对于元素非连续重复的情况(比如1,2,2,1),会把前后出现的相同元素判定为不同项,导致统计错误。要正确统计唯一元素数量,需要记录该行已出现过的所有元素,遇到新元素才计数。
修正后的代码
#include <iostream> #include <unordered_set> // 用哈希集合记录已出现元素 using namespace std; int main() { int M, N; cin >> M >> N; int a[M][N]; // 修正数组下标:C++数组从0开始,原代码用1会触发越界行为 for (int i = 0; i < M; i++) { for (int j = 0; j < N; j++) { cin >> a[i][j]; } } // 统计每行唯一元素数量 for (int i = 0; i < M; i++) { unordered_set<int> seen; // 存储当前行已出现的元素 int count = 0; for (int j = 0; j < N; j++) { // 元素未出现过则加入集合并计数 if (seen.find(a[i][j]) == seen.end()) { seen.insert(a[i][j]); count++; } } cout << "row-" << (i + 1) << ":" << count << endl; // 行号保持从1开始 } return 0; }
关键修正点
- 数组下标修正:将原代码中从1开始的遍历改为从0开始,避免数组越界的未定义行为;
- 统计逻辑替换:使用
unordered_set记录每行已出现的元素,确保每个元素仅被计数一次,无论是否连续重复; - 输出格式优化:添加换行符让输出更清晰,通过
i+1保持行号从1开始的习惯。
更规范的兼容写法(避免变长数组)
C++标准不支持变长数组(int a[M][N]属于编译器扩展),使用vector可以保证代码的可移植性:
#include <iostream> #include <unordered_set> #include <vector> using namespace std; int main() { int M, N; cin >> M >> N; vector<vector<int>> a(M, vector<int>(N)); for (int i = 0; i < M; i++) { for (int j = 0; j < N; j++) { cin >> a[i][j]; } } for (int i = 0; i < M; i++) { unordered_set<int> seen; int count = 0; for (int num : a[i]) { // 范围for循环简化遍历 if (!seen.count(num)) { seen.insert(num); count++; } } cout << "row-" << (i + 1) << ":" << count << endl; } return 0; }
内容的提问来源于stack exchange,提问作者Sadia_Ishrat
相关产品推荐
相关产品推荐

