假设我有一个数组A[]={8, 9, 11, 14, 16, 20};
,我必须根据另一个数组B[]={6, 5, 1, 2, 4, 3};
进行排序。
排序A
为A[]={20, 16, 8, 9, 14, 11};
因此,A
中将告知B
的排序方式。
B
的第一个元素是最大的,因此A
的第一个元素也是最大的元素。 B
的第三个元素最小,因此A
的第三个元素也是最小的
如果B
已排序,则降级为{100, 84, 74, 51, 5, 1}
,然后A
也会降序排序。
例子:
1.如果B = {12, 8, 14, 156, 2, 84}
,则A
为{11, 9, 14, 20, 8, 16}
2.如果B = {2, 3, 45, 0, 7, 56}
,则A
为{9, 11, 16, 8, 14, 20}
就像我有一些不同年龄的朋友一样,我想根据他们的年龄给他们一些东西。最老的人会得到最大的...比他小的人会得到比那个更小的......等等。
我见过类似的问题,但他们不像我的问题。我的想法是先将两者排序。然后重新安排。
有没有快速解决方案?
答案 0 :(得分:4)
从第一个示例开始,您似乎想要使用索引A
数组来置换B
。但第二个示例显示您实际上确实需要排序,但是根据B
中的值而不是A
中的值进行比较。
所以你需要的是一个带有“排序键功能”的排序功能。 sort键函数应作为参数传递给数组索引。
C qsort
确实采用了一个关键函数,但是关键函数的参数是值被比较,而不是被比较的值的索引 。所以它对你不起作用。
您可能必须编写自己的排序功能。这并不难。如果数组很小,简单的插入排序就可以了:
void sort_by_keys(int *values, int *sortkeys, int size)
{
int i, j;
for (i = 1; i < size; i++) {
j = i;
/* For a usual insertion sort, the condition here
* would be values[j] < values[j-1]. */
while (j > 0 && sortkeys[j] < sortkeys[j-1]) {
swap(values, j, j - 1);
swap(sortkeys, j, j - 1);
j--;
}
}
}
(您必须自己编写swap
。)
如果数组较大,您可以编写自己的递归或迭代快速排序。这也不难。确保您还编写了一些测试用例以确保其有效。您的测试用例应包括空数组和包含1个项目的数组。
答案 1 :(得分:3)
看起来这是一个复制操作而不是排序。
第二个数组显示第一个数组元素的排序。区别在于从第二个数组中减去1以获得已排序数组的偏移量。
const int original_array[]={8, 9, 11, 14, 16, 20};
const int ordering_array[]={6, 5, 1, 2, 4, 3};
int result array[6];
for (unsigned int i = 0;
i < sizeof(original_array)/sizeof(original_array[0]);
++i)
{
int source_index = ordering_array[i] - 1;
result_array[i] = original_array[source_index];
}
答案 2 :(得分:1)
如果我正确理解了您的问题,您希望计算B
的排序排列的倒数,然后按顺序排序A
。您可以使用标准库轻松完成此任务。
int A[] = { 8, 9, 11, 14, 16, 20};
int B[] = { 6, 5, 1, 2, 4, 3};
const auto ASIZE = std::extent<decltype(A)>::value;
const auto BSIZE = std::extent<decltype(B)>::value;
// A and B must be the same size
assert(ASIZE == BSIZE);
// p = sorted permutation of B largest to smallest
std::vector<size_t> p(ASIZE);
std::iota(p.begin(), p.end(), 0);
std::sort(p.begin(), p.end(), [&](size_t i1, size_t i2) { return B[i1] > B[i2]; });
// pinv = inverse of p
std::vector<size_t> pinv(ASIZE);
for (size_t i = 0; i < ASIZE; ++i)
pinv[p[i]] = i;
// Sort A largest to smallest
std::sort(std::begin(A), std::end(A), [&](int v1, int v2) { return v1 > v2; });
然后,您可以通过pinv
间接按照您想要的顺序获取A
。
for (size_t index : pinv)
std::cout << A[index] << " ";
std::cout << std::endl;
// Output is: 20 16 8 9 14 11