Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ember.js/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用std::Sort对二维c数组进行排序_C++_Arrays_Sorting_Stl - Fatal编程技术网

C++ 使用std::Sort对二维c数组进行排序

C++ 使用std::Sort对二维c数组进行排序,c++,arrays,sorting,stl,C++,Arrays,Sorting,Stl,我似乎无法用std::sort对二维c数组进行排序。不过,我可以对一维数组进行排序。这是在C++程序中,我被提交C数组,我希望排序,而不复制它到一个STD::数组。也许有什么方法可以将它转换成std::数组而不复制它?对我来说,这听起来很可疑,因为任何std::array都会在它不拥有的内存上调用析构函数 对一维c样式数组进行排序效果很好: int len = 5; auto one_dim_less = [](int a, int b){ return a < b; }; int o

我似乎无法用std::sort对二维c数组进行排序。不过,我可以对一维数组进行排序。这是在C++程序中,我被提交C数组,我希望排序,而不复制它到一个STD::数组。也许有什么方法可以将它转换成std::数组而不复制它?对我来说,这听起来很可疑,因为任何std::array都会在它不拥有的内存上调用析构函数

对一维c样式数组进行排序效果很好:

int len = 5;
auto one_dim_less = [](int a, int b){
  return a < b;
};
int one_dim[] = {4, 0, 3, 1, 2};
std::sort(one_dim, one_dim + len, one_dim_less);
int len=5;
自动一维小于=[](整数a,整数b){
返回a
尝试按第二个数字对二维c样式数组进行排序无法编译:

int len = 5;
auto two_dim_less = [](int a[2], int b[2]){
  return a[1] < b[1];
};
int two_dim[][2] = {{1,8}, {2,4}, {3,10}, {4,40}, {5,1}};
std::sort(two_dim, two_dim + len, two_dim_less);
int len=5;
自动双精度=[](整数a[2],整数b[2]){
返回a[1]
std::sort()
用于排序的对象是可移动的

数组不可移动(也不可分配)

尝试使用结构数组或
std::pair
s代替

也许有某种方法可以在不复制的情况下将其转换为
std::array
是吗

可能不会转换为
std::array
本身,但另一种方法可能是将2D C样式数组转换为
std::array
引用,仅用于排序。这样做依赖于一个标准,即内存中的
std::array
表示至少从它的C样式数组等价物开始。请参见以下内容:

数组是一个聚合,最多可以用N个字符进行列表初始化 类型可转换为T的元素

在实践中,以下使用
reinterpret_cast
很可能是安全的,但请注意,除非标准中有特殊的例外情况,否则它将正式成为未定义的行为:

#include <algorithm>
#include <array>
#include <iostream>

int main() {
  auto two_dim_less = [](std::array<int, 2>& a, std::array<int, 2>& b) {
      return a[1] < b[1]; };

  int two_dim[][2] = {{1, 8}, {2, 4}, {3, 10}, {4, 40}, {5, 1}};

  std::array<std::array<int, 2>, 5>& arr =
    *reinterpret_cast<std::array<std::array<int, 2>, 5>*>(&two_dim);

  std::sort(arr.begin(), arr.end(), two_dim_less);

  for (int i = 0; i < 5; i++)
    std::cout << two_dim[i][0] << ", " << two_dim[i][1] << '\n';

  return 0;
}


关于使用
std::qsort()
,请注意,由于后者允许内联比较,而前者不允许。

问题是您无法分配C数组,例如,
two_dim[0]=two_dim[1]
无效。复制整个数组所需的时间与排序相比可以忽略不计,因此,你是否抄袭可能并不重要。请注意,如果行很长(不仅仅是像这里这样的大小为2),则对边上的键进行排序并将最终排列应用于末尾的矩阵可能会更有效,以避免每次排序交换2个元素时都复制整行。@Marglisse您对复制数组的时间提出了很好的建议。我希望我的服务需要O(1)空间,但我一制作完整副本,情况就不是这样了。另外,关于嵌套数组内容的要点。相关:注意:std::sort不能保证进行适当的排序。(通常在introsort实现中是这样,但如果使用插入排序,则可能会这样做)谢谢。我无法更改输入,除非我愿意将其复制到我自己的结构中。这很有帮助,因为它澄清了为什么我不能编译它,或者我需要支付复制的费用,或者定义我自己的排序函数。这行吗?@Peter是的,
qsort
应该行得通,因为它直接移动字节,而不是依赖
操作符=
。但请注意,如果它所使用的对象不存在,则会导致未定义的Behvaior
int
s和
int
s的数组是可以复制的,但大多数类(如
std::string
s)不是。在实践中,您可能可以通过
qsort
对大多数类进行排序(除非它们依赖
operator=
来更新指向其位置的外部指针),但您仍然应该小心使用。这是一个很好的答案!我使用的唯一问题是,我正在使用的函数被传递任何长度的数组以及一个长度变量,并且std::array在编译时必须具有长度。我不认为有任何方法可以解决这个问题,但这确实教会了我一些东西。我考虑过它,并意识到我可以将您的方法用于采用任意大小c数组的函数,如下所示:
auto&arrr=*reinterpret_cast(&arr2);标准::排序(arrr,arrr+行,两维以下)
5, 1
2, 4
1, 8
3, 10
4, 40