在 C++ 中对结构向量进行排序

Sorting a vector of structs in C++

我有问题。声明说,比赛的结果是从标准输入中读取的,我必须将最终排名按照已解决问题的数量降序打印到屏幕上。这是我的代码。

#include <cstdio>
#include <vector>
#include <cstdlib>
using namespace std;

struct results
{
  unsigned int id; //id of the team
  unsigned int m; //number of solved problems
};

int comparare(const void * i, const void * j) //compare function for qsort()
{
  return -( *(unsigned int*)i - *(unsigned int*)j );
}

int main()
{

  unsigned int n;
  vector<results> standings; //initializing an array of structs

  scanf("%u", &n); //the size of the vector
  for(unsigned int i=0; i<n; ++i)
  {
    scanf("%u%u", &standings[i].id, &standings[i].m); //reading the elements
    standings.push_back(results());
  }

  qsort(standings, n, sizeof(results), comparare); //sorting the array

  for(unsigned int i=0; i<n; ++i)
    printf("%u %u\n", standings[i].id, standings[i].m); //print the sorted array

  return 0;
}

当我要编译代码时,编译器发现错误

cannot convert 'std::vector' to 'void*' for argument '1' to 'void qsort(void*, size_t, size_t, __compar_fn_t)'

在行qsort(standings, n, sizeof(results), comparare);

我需要做什么来修复这个?

如果您绝对必须在 vector 上使用 qsort(而您没有。也不应该),那么您必须像这样传递它:

qsort(standings.data(), standings.size(), sizeof(results), comparare);

vector::data 获取指向存储在 vector 中的数组的指针。简单地传递一个指向 vector 本身的指针将无济于事。

请注意 vector::data 需要 C++11;如果 data 不可用,请使用 &vector[0]

但实际上,just use std::sort:

std::sort(standings.begin(), standings.end(), [](const results &lhs, const results &rhs) {return lhs.id < rhs.id;});

显然 lambda 需要 C++11;随意为早期的 C++ 版本使用名称空间声明的结构。

您正在使用 C 构造,但应该使用更多的 C++ 构造。 std::sort 通常比 qsort 快,而且它的用法更直观。下面是如何在没有 C++11 的情况下重写它。

#include <iostream>
#include <vector>
#include <algorithm>

struct results {
  unsigned int id; //id of the team
  unsigned int m; //number of solved problems
};

// I guess you're trying to sort on number of solved problems. If not, change `.m` to `.id`
bool comparare(const results lhs, const results rhs) {
  return lhs.m > rhs.m;
}

int main() {

  size_t n;

  std::cout << "Enter number of results: " << std::endl;
  std::cin >> n;

 std::vector<results> standings(n); // Creates std::vector of results with n elements

  // read in id and number of problems solved
  for(size_t i=0; i < n; ++i) {
    std::cin >> standings[i].id >> standings[i].m;
  }

  // sort the array
  std::sort(standings.begin(), standings.end(), comparare);

  // output the sorted array's id
  for(size_t i = 0; i < standings.size(); ++i) {
    std::cout << "In " << i+1 << " place: " << standings[i].id << " with " << standings[i].m << " problems solved." << std::endl;
  }

  return 0;
}

下面是 ideone 示例。

如果值可以超过 INT_MAX,则您的比较函数 comparare 不合适。例如比较 UINT_MAX0 将在返回 UINT_MAX - 0 作为 int 时导致溢出。这是未定义的行为,在常见的平台上它实际上是负面的。

改为使用此比较函数:

//compare function for qsort()
int comparare(const void *i, const void *j) {
    unsigned int ni = *(unsigned int*)i;
    unsigned int nj = *(unsigned int*)j;
    return (ni > nj) - (ni < nj);
}

如果*i分别小于、等于或大于*j,则returns、-101

在 C++ 中,还有其他更惯用的数组排序方法。