对 class 个对象的列表进行排序
qsort a list of class objects
我正在为现有库编写排序代码,因此无法更改数据模型
我有以下
class Point
{
//Some functions
public:
float x, y, z;
};
int less_than_key (const void *arg1, const void *arg2)
{
Point *r1 = (Point*) arg1;
Point *r2 = (Point*) arg2;
if(r1->z < r2->z )
return -1;
else if(r1->z > r2->z )
return 1;
else
return 0;
}
int main()
{
list<Point> myPoints;
Point p;
p.x = 0;
p.y = 0;
p.z = 0;
myPoints.push_back(p);
p.x = 0;
p.y = 0;
p.z = 6;
myPoints.push_back(p);
p.x = 0;
p.y = 0;
p.z = 2;
myPoints.push_back(p);
for(int i=0; i<myPoints.size(); i++)
cout<<" Point "<<p[i].x<<", "<<p[i].y<<", "<<p[i].z<<"\n";
qsort(&myPoints, myPoints.size(), sizeof(Point), less_than_key);
for(int i=0; i<myPoints.size(); i++)
cout<<"Point "<<p[i].x<<", "<<p[i].y<<", "<<p[i].z<<"\n";
}
我想根据 z 值对对象进行排序。
我期望的输出如下
Before sorting
Point 0, 0, 0
Point 0, 0, 6
Point 0, 0, 2
After sorting
Point 0, 0, 0
Point 0, 0, 2
Point 0, 0, 6
当我 运行 以下代码时,它在排序调用期间崩溃,我得到以下错误
terminated with signal 11
我在其他解决方案中读到我应该通过以下列表
qsort(&myPoints[0], myPoints.size(), sizeof(Point), less_than_key);
但是当我尝试编译它时,我得到以下结果
no match for 'operator[]' (operand types are 'std::list<Point>' and 'int')
Stl 列表有它自己的接受比较函数的排序函数。您可以编写一个比较函数,该函数采用两个引用 Point 对象并将其传递给 myPoints.sort(..)
您可以将 std::sort 与 lambda 表达式一起使用,这是一个示例:
#include <algorithm>
std::list<Point> myPoints;
//adding points to list...
std::sort(myPoints.begin(), myPoints.end(), [](const Point& lhs, const Point& rhs)
{
return lhs.z < rhs.z;
});
for(int i=0; i<myPoints.size(); i++)
cout<<"Point "<<p[i].x<<", "<<p[i].y<<", "<<p[i].z<<"\n";
上面的代码将排序,然后打印排序后的点列表
qsort
是老派的 C。它需要 4 个参数:
ptr - pointer to the array to sort
count - number of elements in the array
size - size of each element in the array in bytes
comp - comparison function which returns a negative integer value if the first argument is less than the second,
a positive integer value if the first argument is greater than the second and zero if the arguments are equal.
给出的是
- 指向
list
的指针
- 数组中的元素数
- 数组中每个元素的大小(以字节为单位)
- 比较函数
是指向 list
的指针要了你的命。我怀疑这是 std::list
,但无法证明这一点。不管它是什么,它都是一个模板化的数据结构,这让事情变得毛茸茸。它不是数组,不应用作数组。
qsort
尝试将其用作数组,并引用沙丘:
They tried and failed?
They tried and died.
现在,据我们所知,list
可能是一个非常 simple structure,其中包含一个 Point
的数组,其位置完美地与实例的开头对齐--包含数组的地址与实例化 list
的地址相同——但崩溃表明并非如此。
并且如果 list
是动态数组(根据其用法建议)或链表(根据名称和用法建议),则 list
实例甚至不包含其数据.它包含指向数据的指针。 qsort
没有数组可供使用,它会快速 运行 通过存储在 list
中的少量数据,从另一边进入狂野古怪的 [=34= 世界].也就是说,如果您将非数组传递给 qsort
实例,您已经遇到未定义行为。
解决方案是使用 C++ 的 built in std::sort
if list
has an iterator interface. if list
is really std::list
there may be performance advantages in using std::list::sort
。如果两者都不是真的,并且 list
是一个不幸命名的自定义 class,您将不得不编写自己的排序例程(或者做一些聪明的事情并放弃自定义 class 以支持库容器)。
我正在为现有库编写排序代码,因此无法更改数据模型 我有以下
class Point
{
//Some functions
public:
float x, y, z;
};
int less_than_key (const void *arg1, const void *arg2)
{
Point *r1 = (Point*) arg1;
Point *r2 = (Point*) arg2;
if(r1->z < r2->z )
return -1;
else if(r1->z > r2->z )
return 1;
else
return 0;
}
int main()
{
list<Point> myPoints;
Point p;
p.x = 0;
p.y = 0;
p.z = 0;
myPoints.push_back(p);
p.x = 0;
p.y = 0;
p.z = 6;
myPoints.push_back(p);
p.x = 0;
p.y = 0;
p.z = 2;
myPoints.push_back(p);
for(int i=0; i<myPoints.size(); i++)
cout<<" Point "<<p[i].x<<", "<<p[i].y<<", "<<p[i].z<<"\n";
qsort(&myPoints, myPoints.size(), sizeof(Point), less_than_key);
for(int i=0; i<myPoints.size(); i++)
cout<<"Point "<<p[i].x<<", "<<p[i].y<<", "<<p[i].z<<"\n";
}
我想根据 z 值对对象进行排序。 我期望的输出如下
Before sorting
Point 0, 0, 0
Point 0, 0, 6
Point 0, 0, 2
After sorting
Point 0, 0, 0
Point 0, 0, 2
Point 0, 0, 6
当我 运行 以下代码时,它在排序调用期间崩溃,我得到以下错误
terminated with signal 11
我在其他解决方案中读到我应该通过以下列表
qsort(&myPoints[0], myPoints.size(), sizeof(Point), less_than_key);
但是当我尝试编译它时,我得到以下结果
no match for 'operator[]' (operand types are 'std::list<Point>' and 'int')
Stl 列表有它自己的接受比较函数的排序函数。您可以编写一个比较函数,该函数采用两个引用 Point 对象并将其传递给 myPoints.sort(..)
您可以将 std::sort 与 lambda 表达式一起使用,这是一个示例:
#include <algorithm>
std::list<Point> myPoints;
//adding points to list...
std::sort(myPoints.begin(), myPoints.end(), [](const Point& lhs, const Point& rhs)
{
return lhs.z < rhs.z;
});
for(int i=0; i<myPoints.size(); i++)
cout<<"Point "<<p[i].x<<", "<<p[i].y<<", "<<p[i].z<<"\n";
上面的代码将排序,然后打印排序后的点列表
qsort
是老派的 C。它需要 4 个参数:
ptr - pointer to the array to sort
count - number of elements in the array
size - size of each element in the array in bytes
comp - comparison function which returns a negative integer value if the first argument is less than the second, a positive integer value if the first argument is greater than the second and zero if the arguments are equal.
给出的是
- 指向
list
的指针
- 数组中的元素数
- 数组中每个元素的大小(以字节为单位)
- 比较函数
是指向 list
的指针要了你的命。我怀疑这是 std::list
,但无法证明这一点。不管它是什么,它都是一个模板化的数据结构,这让事情变得毛茸茸。它不是数组,不应用作数组。
qsort
尝试将其用作数组,并引用沙丘:
They tried and failed?
They tried and died.
现在,据我们所知,list
可能是一个非常 simple structure,其中包含一个 Point
的数组,其位置完美地与实例的开头对齐--包含数组的地址与实例化 list
的地址相同——但崩溃表明并非如此。
并且如果 list
是动态数组(根据其用法建议)或链表(根据名称和用法建议),则 list
实例甚至不包含其数据.它包含指向数据的指针。 qsort
没有数组可供使用,它会快速 运行 通过存储在 list
中的少量数据,从另一边进入狂野古怪的 [=34= 世界].也就是说,如果您将非数组传递给 qsort
实例,您已经遇到未定义行为。
解决方案是使用 C++ 的 built in std::sort
if list
has an iterator interface. if list
is really std::list
there may be performance advantages in using std::list::sort
。如果两者都不是真的,并且 list
是一个不幸命名的自定义 class,您将不得不编写自己的排序例程(或者做一些聪明的事情并放弃自定义 class 以支持库容器)。