矩阵排序后段错误及输入查找序列时程序终止问题求助
解决不规则矩阵排序与查找的段错误问题
核心错误排查与修复
1. 输入处理逻辑缺陷(直接终止/非法内存访问)
输入时未正确处理流状态,或允许空行进入矩阵,是导致程序终止和段错误的常见原因。修复后的输入处理代码(不使用sstream):
#include <iostream> #include <vector> #include <string> #include <algorithm> #include <limits> using namespace std; vector<vector<int>> readMatrix() { vector<vector<int>> mat; string token; while (true) { if (!cin >> token) { cin.clear(); cin.ignore(numeric_limits<streamsize>::max(), '\n'); continue; } if (token == "*") break; vector<int> row; try { row.push_back(stoi(token)); } catch (...) { cin.ignore(numeric_limits<streamsize>::max(), '\n'); continue; } while (cin >> token) { if (token == "*") break; try { row.push_back(stoi(token)); } catch (...) { cin.ignore(numeric_limits<streamsize>::max(), '\n'); row.clear(); break; } } if (!row.empty()) { mat.push_back(row); } } return mat; }
要点:
- 每次读取前检查输入流状态,处理非法输入导致的
fail状态 - 用
try-catch包裹stoi,避免非法数字触发未定义行为 - 确保只有非空行被加入矩阵,避免后续排序时访问空容器
2. 排序比较函数(Criterion)的逻辑错误
原函数可能未处理空行,或字典序比较方向错误,导致排序时触发段错误。修复后的Criterion函数:
bool Criterion(const vector<int>& a, const vector<int>& b) { if (a.empty()) return false; if (b.empty()) return true; int max_a = *max_element(a.begin(), a.end()); int max_b = *max_element(b.begin(), b.end()); if (max_a != max_b) { return max_a > max_b; } return a > b; } void SortByOrderGoodness(vector<vector<int>>& mat) { sort(mat.begin(), mat.end(), Criterion); }
要点:
- 优先处理空行,避免
max_element访问空容器触发段错误 - 字典序降序直接使用
vector的operator>,简洁且符合需求
3. lower_bound查找的兼容性问题
降序排序后的容器,lower_bound的比较函数必须与排序逻辑一致,否则会导致查找错误或迭代器越界。正确的查找代码:
vector<int> readTarget() { vector<int> target; string token; cout << "输入待查找序列(以*结束):"; while (cin >> token) { if (token == "*") break; try { target.push_back(stoi(token)); } catch (...) { cin.ignore(numeric_limits<streamsize>::max(), '\n'); target.clear(); cout << "输入非法,请重新输入:"; } } return target; } void findSequence(const vector<vector<int>>& mat, const vector<int>& target) { if (mat.empty() || target.empty()) { cout << "矩阵或查找序列为空,无法查找" << endl; return; } auto it = lower_bound(mat.begin(), mat.end(), target, [](const vector<int>& a, const vector<int>& b) { return Criterion(b, a); }); if (it != mat.end() && *it == target) { cout << "找到序列,位置:" << it - mat.begin() << endl; } else { cout << "未找到序列" << endl; } }
要点:
- 查找前检查矩阵和目标序列是否为空,避免访问空迭代器
- 自定义
lower_bound的比较函数,确保与Criterion的排序逻辑兼容,保证查找结果正确
完整流程示例
int main() { cout << "输入矩阵(行首输入*结束输入,每行以*结束):" << endl; vector<vector<int>> mat = readMatrix(); SortByOrderGoodness(mat); cout << "排序后的矩阵:" << endl; for (const auto& row : mat) { for (int num : row) { cout << num << " "; } cout << endl; } vector<int> target = readTarget(); findSequence(mat, target); return 0; }
关键注意事项
- 始终检查容器是否为空,避免访问空迭代器或空容器的元素
- 输入流状态必须及时处理,防止非法输入导致程序假死或终止
- 排序与查找的比较逻辑必须一致,否则
lower_bound无法正确工作
内容的提问来源于stack exchange,提问作者tom anthony
相关产品推荐
相关产品推荐

