我有一个2d数组,我想用C ++中给定的qsort()函数快速排序:
unsigned work[N][3];
我想通过第三个索引对“work”数组进行排序...如果work[i]
在work[j]
之前work[i][2]>work[j][2]
,那么{/ 1}}。
我知道我需要使用一个函数来比较它,但我不知道如何做到这一点。
修改 如果我会这样做,那会有所帮助:
unsigned work[3][N];
qsort(work[2], N, sizeof(unsigned), compare);
比较如下:
int compare(const void* a, const void* b)
{
return(*(unsigned*)a-*(unsigned*)b);
}
答案 0 :(得分:4)
嗯,简短的回答是根本不使用std::qsort
,而是std::sort
。但不幸的是后者不起作用,因为unsigned int[3]
不可分配。所以这是最简单的std::qsort
解决方案。
首先我们定义一个自定义比较器函数:
// return -1 if a before b, 1 if after, 0 if equal
int compare(const void *a, const void *b)
{
const unsigned int *arg1 = reinterpret_cast<const unsigned int*>(a);
const unsigned int *arg2 = reinterpret_cast<const unsigned int*>(b);
if(arg1[2] > arg2[2])
return -1;
if(arg1[2] < arg2[2])
return 1;
return 0;
}
然后我们用它来对数组进行排序。请记住,work
是一个数组数组,因此work[0]
是一个3 unsigned int
的数组,没有任何方式涉及指针间接。所以它非常适合按std::qsort
排序:
std::qsort(work, sizeof(work)/sizeof(work[0]), sizeof(work[0]), compare);
顺便说一下,第三个元素用2
索引,因为我们通常在C ++(和许多其他编程语言)中开始计算0
。
编辑:尽管如此,最好的解决办法是放弃这个数组并使用更适合C ++的东西,比如std::vector
std::array<unsigned int,3>
个(或者typedef std::array<unsigned int,3> uint3;
std::vector<uint3> work(N);
任何其他适合实际情况的数据结构:
std::sort(std::begin(work), std::end(work),
[](const uint3 &a, const uint3 &b) { return a[2] > b[2]; });
然后可以用简单的方法对其进行排序:
std::array
或者,如果您没有C ++ 11(尽管在这种情况下您也不会有struct compare
{
bool operator()(const uint3 &a, const uint3 &b) const
{
return a[2] > b[2];
}
};
std::sort(work.begin(), work.end(), compare());
并且需要开始考虑除了仅仅3个数组之外的合理数据结构):< / p>
std::sort
作为更清晰代码的奖励,您std::qsort
的{{1}}可能会略微提升{{1}}。
答案 1 :(得分:2)
是的,你可以qsort()
这个。 qsort()
通过获取所需的线性块“stuff”,将其划分为统一大小的块,其中你指定大小(以字节为单位),然后喂你每个块分区的基址以进行比较。
首先,确定您需要的尺寸。很明显,你要排序的“事物”是数组行三个元素。第二,编写一个比较器,它可以接受两个诸如指针这样的东西的基地址,在我们的例子中,一个简单的指针就可以工作,因为它很好地剥离了外部数组维度。最后,实际比较将是我们给出的每个指针p[2]
的三个元素深度(p
准确):
让我们充实代码:
#include <stdlib.h>
#include <stdio.h>
#include <memory.h>
#include <time.h>
static const size_t ROWSIZE = 3;
static void print_array(int rows, int ar[rows][ROWSIZE])
{
int i,j;
for (i=0;i<rows;++i)
{
for (j=0; j<ROWSIZE; printf("%d ", ar[i][j++]));
printf("\n");
}
printf("\n");
}
// compare function
static int compare_row(const void* left, const void* right)
{
const int *ileft = left, *iright = right;
return ileft[ROWSIZE-1] - iright[ROWSIZE-1];
}
int main()
{
int ar[10][ROWSIZE] = {0}, i;
// fill with random junk from 10 to 99
srand((unsigned)time(0));
for (i=0;i<ROWSIZE * sizeof(ar)/sizeof(ar[0]); ++i)
ar[i/ROWSIZE][i%ROWSIZE] = 10 + (rand() % 90);
// print prior to sort.
print_array(sizeof(ar)/sizeof(ar[0]), ar);
// send to qsort
qsort(ar, sizeof(ar)/sizeof(ar[0]), sizeof(ar[0]), compare_row);
// print again after sort.
print_array(sizeof(ar)/sizeof(ar[0]), ar);
return EXIT_SUCCESS;
}
示例输出
50 14 23
69 81 93
30 72 18
26 49 29
51 87 58
18 74 40
26 61 26
43 80 27
27 61 34
13 66 89
30 72 18
50 14 23
26 61 26
43 80 27
26 49 29
27 61 34
18 74 40
51 87 58
13 66 89
69 81 93