[英]Using the sort function on vectors on different variables
I have data that has been given in coordinates.我有坐标中给出的数据。 I made their classes and the classes are made of this:
我做了他们的课,这些课是由这个组成的:
Point2D (int x, int y)
Point3D (int z) //#include Point2D.h
Line2D (Point2D pt1, Point2D pt2)
Line3D (Point3D pt1, Point3D pt2)
Now, I am supposed to be able to sort the data according to any filtering criteria (each class is a filtering criterion), any sorting criteria ( x, y, z
, or their product) and sorting order (either ascending or descending) The filtering criteria specify which set of records to be displayed.现在,我应该能够根据任何过滤条件(每个类都是一个过滤条件)、任何排序条件(
x, y, z
或它们的乘积)和排序顺序(升序或降序)对数据进行排序。过滤条件指定要显示的记录集。
I've created a generic sort algorithm, but I am supposed to be using the sort function from the STL algorithm.我已经创建了一个通用的排序算法,但我应该使用 STL 算法中的排序函数。 I'm pasting my algo below, but can someone simplify it using the
std::sort
function.我在下面粘贴我的算法,但有人可以使用
std::sort
函数简化它。
void sort(
vector<Point2D*>& point2DList,
vector<Point3D*>& point3DList,
vector<Line2D*>& line2DList,
vector<Line3D*>& line3DList,
string filterCriteria, string sortingCriteria, string sortingOrder)
{
if (filterCriteria == "Point2D")
{
for (int i = 0; i < (int)point2DList.size() - 1; i++)
{
int index = i;
for (int j = i + 1; j < point2DList.size(); j++)
{
if (sortingOrder == "ASC")
{
if ((sortingCriteria == "x-ordinate" && point2DList[index]->getX() > point2DList[j]->getX()) ||
(sortingCriteria == "y-ordinate" && point2DList[index]->getY() > point2DList[j]->getY()))
index = j;
}
else if (sortingOrder == "DSC")
{
if ((sortingCriteria == "x-ordinate" && point2DList[index]->getX() < point2DList[j]->getX()) ||
(sortingCriteria == "y-ordinate" && point2DList[index]->getY() < point2DList[j]->getY()))
index = j;
}
}
Point2D* ptr = point2DList[i];
point2DList[i] = point2DList[index];
point2DList[index] = ptr;
}
}
}
I have only pasted the first part of the algo that involves the Point2D
objects, the same flow I have applied for the other 3 classes as well.我只粘贴了涉及
Point2D
对象的算法的第一部分,我也为其他 3 个类应用了相同的流程。
Fist of all to my understanding, you are using a single sort
function (non-template) for sorting different data structure.首先,据我所知,您正在使用单个
sort
函数(非模板)对不同的数据结构进行排序。 This is not how you make the generic sort function.这不是您制作通用排序功能的方式。 You need to go for function templates .
你需要去寻找功能模板。
Secondly, the vectors of raw-pointers to those data structure does not look appropriate.其次,指向这些数据结构的原始指针的向量看起来不合适。 The
std::vector
created/ allocates it's underline data dynamically in free storage, meaning you do not need to put each its elements in manually created memory. std::vector
created/ 在空闲存储中动态分配它的下划线数据,这意味着您不需要将每个元素放入手动创建的内存中。 If that can not be avoided, I would suggest smart pointers rather than raw pointers there.如果无法避免,我会建议使用智能指针而不是原始指针。
Thirdly the filterCriteria
, sortingOrder
, and sortingCriteria
could have been enum
s rather than std::string
s.第三,
filterCriteria
、 sortingOrder
和sortingCriteria
可能是enum
而不是std::string
。
Following is the modified sort
function, which actually only considers your requirement of using std::sort
.以下是修改后的
sort
函数,它实际上只考虑了您使用std::sort
要求。 Also note that I have used, lambda functions for the custom sorting criteria, which you could read more here: What is a lambda expression in C++11?另请注意,我已经使用了用于自定义排序标准的lambda 函数,您可以在此处阅读更多内容: 什么是 C++11 中的 lambda 表达式?
// enumerations for case checking!
enum class FilterCriteria { Point2D = 0, Point3D/*, other cases*/ };
enum class SortingCriteria { x_ordinate = 0, y_ordinate };
enum class SortingOrder { ASC = 0, DSC };
void sort(
std::vector<Point2D*>& point2DList,
std::vector<Point3D*>& point3DList,
std::vector<Line2D*>& line2DList,
std::vector<Line3D*>& line3DList,
const FilterCriteria filterCriteria,
const SortingOrder sortingOrder,
const SortingCriteria sortingCriteria)
{
const auto xLessCompare = [](const Point2D* lhs, const Point2D* rhs) { return lhs->x < rhs->x; };
const auto yLessCompare = [](const Point2D* lhs, const Point2D* rhs) { return lhs->y < rhs->y; };
const auto xGreaterCompare = [](const Point2D* lhs, const Point2D* rhs) { return lhs->x > rhs->x; };
const auto yGreaterCompare = [](const Point2D* lhs, const Point2D* rhs) { return lhs->y > rhs->y; };
switch (filterCriteria)
{
case FilterCriteria::Point2D:
{
if (sortingOrder == SortingOrder::ASC)
{
if (sortingCriteria == SortingCriteria::x_ordinate)
std::sort(point2DList.begin(), point2DList.end(), xGreaterCompare);
else if (sortingCriteria == SortingCriteria::y_ordinate)
std::sort(point2DList.begin(), point2DList.end(), yGreaterCompare);
}
else if (sortingOrder == SortingOrder::DSC)
{
if (sortingCriteria == SortingCriteria::x_ordinate)
std::sort(point2DList.begin(), point2DList.end(), xLessCompare);
else if (sortingCriteria == SortingCriteria::y_ordinate)
std::sort(point2DList.begin(), point2DList.end(), yLessCompare);
}
break;
}
case FilterCriteria::Point3D: {
// ... code
break;
}
default: break;
};
}
I don't have your class definitions, so i made theese, i hope they are like yours.我没有你的类定义,所以我做了这些,我希望它们和你的一样。
If you want to use std::sort
you have 2 options:如果你想使用
std::sort
你有两个选择:
1 option is used if sorting used many times, or if classes are stored in containers, that requires less operator (like std::set
or std::map
) 2 option is good if you sort some structer only in one place in whole code and you need it inline, or you have to overload currently specifed less operator如果多次使用排序,或者如果类存储在容器中,需要较少的运算符(如
std::set
或std::map
),则使用 1 选项 2 如果您在整个代码中仅在一个地方对某个结构体进行排序,则使用 2 选项并且您需要内联,或者您必须重载当前指定的 less 运算符
Here is code with both options, hope it helps.这是两个选项的代码,希望它有所帮助。 If anything makes you struggle, feel free to comment
如果有什么让你挣扎,请随时发表评论
#include <algorithm>
#include <vector>
#include <iostream>
#include <random>
struct Point2D
{
int x;
int y;
Point2D(const int x, const int y) : x{x}, y{y} {}
inline friend bool operator<(const Point2D& p1, const Point2D& p2)
{
return ( p1.x == p2.x ? p1.y < p2.y : p1.x < p2.x );
}
};
// print operator
std::ostream& operator<<(std::ostream& o, const Point2D& p)
{
return o << "( x=" << p.x << ", y=" << p.y << ")";
}
struct Point3D : public Point2D
{
Point3D(const int x, const int y, const int z) : Point2D{ x,y }, z{z} {}
int z;
};
// print operator
std::ostream& operator<<(std::ostream& o, const Point3D& p)
{
return o << "( z=" << p.z << ", x=" << p.x << ", y=" << p.y << ")";
}
// supportive functions for printing
template<typename T>
void print_collection( const std::vector<T>& vec, const char* collection_name )
{
std::cout << collection_name << ": ";
for(const auto& var : vec)
std::cout << var << ", ";
std::cout << std::endl;
}
template<typename T>
void print_ptr_collection( const std::vector<T>& vec, const char* collection_name )
{
std::cout << collection_name << ": ";
for(const auto& var : vec)
std::cout << *var << ", ";
std::cout << std::endl;
}
// support functions for random numbers
int rng()
{
std::random_device engine;
std::uniform_int_distribution<int> ranges{ -100, 100 };
return ranges(engine);
}
int main()
{
std::vector<Point2D> vec1; vec1.reserve(5);
std::vector<Point3D*> vec2; vec2.reserve(5);
// fill
for(int i = 0; i < 5; i++)
{
vec1.emplace_back( rng(), rng() );
vec2.emplace_back( new Point3D{ rng(), rng(), rng() } );
}
// print unsorted
print_collection( vec1, "vec1 unsorted");
print_ptr_collection( vec2, "vec2 unsorted");
// sort with std::sort
std::sort( vec1.begin(), vec1.end() );
std::sort( vec2.begin(), vec2.end(), [](const Point3D* p1, const Point3D* p2) -> bool {
return ( p1->z == p2->z ? (*p1) < (*p2) : p1->z < p2->z );
} );
// print sorted
print_collection( vec1, "vec1 sorted" );
print_ptr_collection( vec2, "vec2 sorted" );
// cleanup
for(int i = 0; i < vec2.size(); i++)
{
delete vec2[i];
vec2[i] = nullptr;
}
}
This is the output:这是输出:
vec1 unsorted: ( x=3, y=66), ( x=-1, y=-65), ( x=-9, y=-70), ( x=29, y=16), ( x=32, y=56),
vec2 unsorted: ( z=-51, x=-57, y=-87), ( z=58, x=49, y=43), ( z=-71, x=-63, y=-87), ( z=23, x=-22, y=13), ( z=-57, x=94, y=-7),
vec1 sorted: ( x=-9, y=-70), ( x=-1, y=-65), ( x=3, y=66), ( x=29, y=16), ( x=32, y=56),
vec2 sorted: ( z=-71, x=-63, y=-87), ( z=-57, x=94, y=-7), ( z=-51, x=-57, y=-87), ( z=23, x=-22, y=13), ( z=58, x=49, y=43),
Edit: forgot to add deleteion of pointers at the end :)编辑:忘了在最后添加删除指针:)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.