多维数组
多维数组存储的其实是指向整数的指针的指针.....
声明4*4*4的三维数组:
char*** temp = new char** [4];
for (int m = 0; m < 4; m++) {
temp[m] = new char* [4];
for (int n = 0; n < 4; n++) {
temp[m][n] = new char[4];
for (int j = 0; j < 4; j++) {
temp[m][n][j] = '0';
}
}
}
初始化:
for (int m = 0; m < 4; m++) {
for (int n = 0; n < 4; n++) {
for (int j = 0; j < 4; j++) {
std::cout << temp[m][n][j] << ",";
}
std::cout << "------";
}
std::cout << std::endl;
}
所以释放内存的时候需要使用for循环来释放:
for (int m = 0; m < 4; m++) {
for (int n = 0; n < 4; n++) {
delete[] temp[m][n];
}
delete[] temp[m];
}
delete[] temp;
很多时候可以避免使用多维数组,因为多维数组存储位置并不连续,有时候缓存不命中到导致效率远远比一维数组更低,所以可以使用一维数组代替多维数组提高性能。
char* test = new char[64];
for (int m = 0; m < 4; m++) {
for (int n = 0; n < 4; n++) {
for (int j = 0; j < 4; j++) {
test[m * 16 + n * 4 + j] = '0';
}
}
}
for (int m = 0; m < 4; m++) {
for (int n = 0; n < 4; n++) {
for (int j = 0; j < 4; j++) {
std::cout << test[m * 16 + n * 4 + j] << ",";
}
std::cout << "------";
}
std::cout << std::endl;
}
delete[] test;
顺带复习一下使用构造函数、析构函数做计时器:
struct Timer1
{
std::chrono::steady_clock::time_point start, end;
Timer1() {
start = std::chrono::high_resolution_clock::now();
}
~Timer1() {
auto end = std::chrono::high_resolution_clock::now();
std::cout << (float)(end - start).count() << std::endl;
}
};
验证:
int main() {
{
Timer1();
char*** temp = new char** [4];
for (int m = 0; m < 4; m++) {
temp[m] = new char* [4];
for (int n = 0; n < 4; n++) {
temp[m][n] = new char[4];
for (int j = 0; j < 4; j++) {
temp[m][n][j] = '0';
}
}
}
for (int m = 0; m < 4; m++) {
for (int n = 0; n < 4; n++) {
for (int j = 0; j < 4; j++) {
std::cout << temp[m][n][j] << ",";
}
std::cout << "------";
}
std::cout << std::endl;
}
for (int m = 0; m < 4; m++) {
for (int n = 0; n < 4; n++) {
delete[] temp[m][n];
}
delete[] temp[m];
}
delete[] temp;
}
{
Timer1();
char* test = new char[64];
for (int m = 0; m < 4; m++) {
for (int n = 0; n < 4; n++) {
for (int j = 0; j < 4; j++) {
test[m * 16 + n * 4 + j] = '0';
}
}
}
for (int m = 0; m < 4; m++) {
for (int n = 0; n < 4; n++) {
for (int j = 0; j < 4; j++) {
std::cout << test[m * 16 + n * 4 + j] << ",";
}
std::cout << "------";
}
std::cout << std::endl;
}
delete[] test;
}
}
输出:
、
证明确实在多维数组中使用一维数组代替会有良好效果。但某些情况下,如果申请的一维数组过大,可能会报错,因为内存中可能不存在一长串连续内存。
排序
std::vector<int> values = { 3,1,4,6,2 };
正序:
std::sort(values.begin(), values.end());
std::sort(values.begin(), values.end(), [](int a, int b) {
return a < b;
});
倒序:
std::sort(values.begin(), values.end(), std::greater<int>());
std::sort(values.begin(), values.end(), [](int a, int b) {
return a > b;
});
猜猜下面代码运行结果???
std::sort(values.begin(), values.end(), [](int a, int b) {
if (a == 1)
return false;
if (b == 1)
return true;
return a < b;
});
std::sort(values.begin(), values.end(), [](int a, int b) {
if (a == 1)
return false;
if (b == 1)
return false;
return a < b;
});
都是升序排列,但是第一个1排在了最后,第二个1排在了中间,gpt给出如下解释:
第一个Lambda表达式的逻辑是:
如果a是1,它不认为a比b小,返回false。
如果b是1,它认为a比b小,返回true。
如果两者都不是1,那么它按照自然顺序(a < b)来比较。
结果是,1会排在所有其他数字之后,因为每当与1比较时,1都被视为“较大”的数。
第二个Lambda表达式的逻辑是:
如果a是1,那么它不认为a比b小,返回false。
如果b是1,同样地,它也不认为b比a小,返回false。
如果两者都不是1,那么它按照自然顺序(a < b)来比较。
结果是,1既不排在最前面,也不排在最后面,而是根据其他数字的相对位置,被排列在中间。
至于为什么都返回false的时候1被排列在了中间,这是因为在这个特定的比较逻辑中,1既不比其他数字小,也不比其他数字大。因此,它在排序过程中不会被置于序列的开始或结束,而是根据其他数字的相对位置来决定其位置。这种排序方式称为“稳定排序”,意味着相等元素的相对顺序在排序后保持不变。由于1与任何非1数字比较时都返回false,所以它的相对位置取决于它在排序前的位置和其他数字的排序方式。