c++ - 在 C++ 中对多维数组进行排序
问题描述
如下代码所示对二维数组进行排序是否安全?
int a[3][3];
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
cin >> a[i][j];
}
}
sort(&a[0][0], &a[0][0] + 3 * 3); // the built-in sort function
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
cout << a[i][j] << ' ';
}
cout << '\n';
}
我们可以将这种方式推广到任何多维数组吗?
解决方案
如下代码所示对二维数组进行排序是否安全?
我对极端情况的洞察力并不好,但只要您不访问非法索引,这似乎是安全的。
分配的二维数组位置在内存中是连续的,例如a[3][3]
:
a[0][0]..a[0][1]..a[0][2]..a[1][0]..a[1][1]..a[1][2]..a[2][0]..a[2][1]..a[2][2]
由于std::sort
使用 [first,last) 范围,因此将其应用于该范围 from a[0][0]
toa[2][2]+1
是有意义的,即:
sort(&a[0][0], &a[2][2]+1);
或从基地址而不是结束位置考虑:
sort(&a[0][0], &a[0][0]+(3*3));
给出了正确的答案,尽管乍一看它似乎是未定义的行为,&array[0][0]+(dim1*dim2)
似乎超出了范围。但它从不访问非法索引,因为对于2D 数组,指针(跟随指针算术)只会从a[0][0]
到a[2][2]
,跟随整数大小的增量。int
到目前为止,它似乎是正确或安全的。
然而,Jarod 想要传达的也是正确的——我们在上下文中有两个数组,并且a[0][0]..a[2][2]
与 不同a[0]..a[9]
,因为前者的类型仍然属于int(*)[3]
,考虑到我们的数组a[3][3]
传递给std::sort
。
详细解释他所说的:
传递 from(&a[0][2]) + 1
是数组末尾的一个过去a[0]
。&a[1][0]
,在同一位置属于另一个数组:
a[0][0]..a[0][1]..a[0][2] -> Array 1
// a[0][2] + 1 -> exceeds index of the first array among the three arrays of the array which forms a[3][3]
a[1][0]..a[1][1]..a[1][2] -> Array 2
a[2][0]..a[2][1]..a[2][2] -> Array 3
如果它仍然是正确的(如果你假设)那么它只有((&a[0][2]) + 1) - &a[1][0]
等于 0 才有意义。但它被证明显示未定义的行为而不是 0,正如 Jarod 在他的演示中所证明的那样,在(&a[0][0] + 3)
和之间有一个相应的例子&a[1][0]
. (Clang 显示一个错误,可用于证明 UB 案例的合理性)
我们可以将这种方式推广到任何多维数组吗?
是的,为什么不?
这是一个三维的:
#include <iostream>
#include <algorithm>
int main()
{
int a[2][2][2];
for (int i = 0; i < 2; i++)
for (int j = 0; j < 2; j++)
for (int k = 0; k < 2; k++)
std::cin >> a[i][j][k];
std::sort(&a[0][0][0], &a[0][0][0] + 2 * 2 * 2);
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
for (int k = 0; k < 2; k++)
std::cout << a[i][j][k] << " ";
std::cout << "\n";
}
}
}
推荐阅读
- spring-security - 使用 private_key_jwt 而不是 client_secret_basic 时 Spring Security 中的“invalid_client”
- python - 从 PendingRollbackError 中恢复并允许后续查询
- android - 是否可以监听其他应用程序的意图?
- java - 我正在用 Java 编写代码来检查字符串是否为回文。但是,当涉及空格时,代码会中断
- regex - 仅当按顺序找到左右分隔符时,正则表达式才匹配
- luarocks - luarocks 安装外星人模块找不到 libffi.dll
- nginx - 如何确保 nginx 解析 proxy_pass 中的变量 DNS?
- c# - 按结果分组
- apache - Mapfish 打印服务器返回“HTTP 状态 400 – 错误请求”作为 API 响应
- java - H2 导致 org.h2.jdbc.JdbcSQLIntegrityConstraintViolationException 而 Hibernate 不会