在 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_MAX
和 0
将在返回 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、-1
、0
或1
。
在 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_MAX
和 0
将在返回 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、-1
、0
或1
。
在 C++ 中,还有其他更惯用的数组排序方法。