使用std::sort排序静态二维数组出现编译错误的解决方法
错误产生原因
std::sort在排序流程中需要对元素做移动、交换、临时存储操作,要求迭代器指向的元素类型满足可拷贝构造、可赋值的要求。
你代码里待排序的ministers是原生C风格二维数组int [1010][2],当你传入ministers和ministers+n作为排序范围时,迭代器指向的元素类型是长度为2的int数组int[2]。而C++原生数组有两个特性直接导致编译失败:
- 原生数组不支持直接赋值操作,对应报错里的
invalid array assignment - 原生数组不能用普通值初始化的方式构造临时对象,对应报错里的
array must be initialized with a brace-enclosed initializer
另外你写的cmp函数参数写int m1[2]在C++里会自动退化为指针,实际等价于const int* m1, const int* m2,比较逻辑本身是符合你预期排序规则的,问题和cmp逻辑无关。
修复方案
选以下任意一种方案修改即可,排序逻辑不需要调整,就能得到你预期的先按第二列升序、第二列相同时按第一列升序的结果。
- 方案1:用标准库固定长度数组
std::array替换原生二维数组,改动量最小std::array是标准库封装的固定长度数组类型,原生支持拷贝、赋值操作,完全满足std::sort的类型要求,还能保留原来用下标访问元素的写法:
#include <cstdio> #include <algorithm> #include <array> using namespace std; array<int, 2> ministers[1010]; int n, a, b; static bool cmp(const array<int,2>& m1, const array<int,2>& m2) { if (m1[1] != m2[1]) return m1[1] < m2[1]; return m1[0] < m2[0]; } int main() { scanf("%d%d%d", &n, &a, &b); for (int i = 0; i < n; i++) scanf("%d %d", &ministers[i][0], &ministers[i][1]); std::sort(ministers, ministers + n, cmp); return 0; }
- 方案2:定义结构体存储每行的两个整数
结构体默认支持拷贝、赋值,语义更清晰,适合后续要给每行元素加其他字段的场景:
#include <cstdio> #include <algorithm> using namespace std; struct Minister { int a; int b; } ministers[1010]; int n, king_a, king_b; static bool cmp(const Minister& m1, const Minister& m2) { if (m1.b != m2.b) return m1.b < m2.b; return m1.a < m2.a; } int main() { scanf("%d%d%d", &n, &king_a, &king_b); for (int i = 0; i < n; i++) scanf("%d %d", &ministers[i].a, &ministers[i].b); std::sort(ministers, ministers + n, cmp); return 0; }
- 方案3:保留原生二维数组,额外创建索引数组排序
如果不想改动原有数组的定义,可以创建一个存行号的索引数组,排序时比较索引对应行的元素值,排序后通过索引访问有序结果,这种方式不需要移动二维数组的元素,适合数组元素体积很大的场景:
#include <cstdio> #include <algorithm> using namespace std; int ministers[1010][2]; int idx[1010]; int n, a, b; static bool cmp(int i, int j) { if (ministers[i][1] != ministers[j][1]) return ministers[i][1] < ministers[j][1]; return ministers[i][0] < ministers[j][0]; } int main() { scanf("%d%d%d", &n, &a, &b); for (int i = 0; i < n; i++) { scanf("%d %d", &ministers[i][0], &ministers[i][1]); idx[i] = i; } std::sort(idx, idx + n, cmp); // 访问有序结果时用ministers[idx[i]][0]、ministers[idx[i]][1]即可 return 0; }
内容的提问来源于stack exchange,提问作者Xiaotian Hong
相关产品推荐
相关产品推荐

