根据另一个数组的顺序对数组进行排序

时间:2016-05-15 18:45:19

标签: c++ arrays sorting

假设我有一个数组A[]={8, 9, 11, 14, 16, 20};,我必须根据另一个数组B[]={6, 5, 1, 2, 4, 3};进行排序。

排序AA[]={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}

就像我有一些不同年龄的朋友一样,我想根据他们的年龄给他们一些东西。最老的人会得到最大的...比他小的人会得到比那个更小的......等等。

我见过类似的问题,但他们不像我的问题。我的想法是先将两者排序。然后重新安排。

有没有快速解决方案?

3 个答案:

答案 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