【问题标题】:Sorting a vector inside a custom class C++ using std::sort使用 std::sort 在自定义类 C++ 中对向量进行排序
【发布时间】:2015-06-12 06:54:44
【问题描述】:

如何使用 std::sort 对自定义类中的两个向量进行排序?

例如,假设我有一个包含两个向量、id 和标记的类。初始化向量后,我想按标记对此类的元素进行排序,保留 id 中的排序顺序。

我尝试使用自定义std::sort 函数来执行此操作。

class Example
{
public:
    void init();
    static bool sortByMarks(const Example &lhs, const Example &rhs);
    //....other functions

private:
    vector<int> ids;
    vector<int> marks;
    //....other variables   
}
void Partition::init()
{
    ids.resize(5);
    marks.resize(5);
    for(int i=0;i<5;i++)
         ids[i]=i+1;
    marks[0]=47;marks[1]=44;marks[2]=88;marks[3]=52;marks[4]=46;
}
bool Partition::sortByMarks(const Example &lhs, const Example &rhs);
{
    return lhs.marks < rhs.marks;
}

编辑:[通过将 Example:: 添加到函数调用来解决此问题] 我在调用此函数时遇到问题。我尝试了以下方法:

Example e; 
sort(&e, &e, Example::sortByMarks);

示例输入:

ids : 1,2,3,4,5 marks: 47,44,88,52,46

样本输出:

ids : 2,5,1,4,3 marks: 44,46,47,52,88

感谢任何帮助!

编辑:标记向量是我想要排序的(ids 也应该相应地更改)

【问题讨论】:

  • 首先,您需要添加一个 ;在你的课结束时。我有两个问题:您想使用矢量标记进行排序吗?
  • 您到底想对什么进行排序? e.marks?然后相应地更改e.ids 以保持 id-marks 配对?
  • 您想对idsmarks 进行排序,其中ids 数组根据marks 值在同一索引处进行排序?例如,如果您有和ids = { 1, 2, 3}marks = { 98, 54, 89 },您希望排序后的数组看起来像:id = {2, 3, 1}marks = {54, 89, 98}
  • @MichaelBurr 这正是我想要的。我在我的问题中添加了示例输入/输出。
  • range-v3ranges::sort(ranges::view::zip(marks, ids));。这在技术上首先按标记排序,然后按 ID。

标签: c++ sorting vector


【解决方案1】:

我认为你不能用这样的向量来做到这一点。您需要以某种方式将 id 与标记结合起来,例如使用地图、成对向量或像这样:

class Example{
public:
    void init();
    void sortByMarks();

private:
    struct Students{
        int ids;
        int marks;
    };
    std::vector < Students > students;

};

void Example::sortByMarks(){
    std::sort(students.begin(), students.end(), [](Students a, Students b){
        return a.marks < b.marks;
    });
}


int main(){
    Example e;
    e.sortByMarks();
}

或者您可以编写自己的排序:

void selection_sort(){
    int size = marks.size();
    for (int i = 0; i < size - 1; i = i + 1){
        int min = i;
        for (auto j = i + 1; j < size; j = j + 1){
            if (marks[j] < marks[min]){ min = j; }
        }
        std::swap(marks[i], marks[min]);
        std::swap(ids[i], ids[min]);    // add this extra line
    }
}

【讨论】:

  • 我担心这可能是解决方案,因为我必须在我的实际代码中进行很多更改!谢谢。
  • 好吧,您也可以编写自己的排序函数。如果您已经有有效的排序算法,则只需要一行额外的代码。
【解决方案2】:
// .h file
class MarkersDetector
{
    public:
        void sortMarkers(std::vector<cv::Point2f> &markers);
        // Other functions...
    private:
        // Other variables...
};

// .cpp file
// Function for sort the marker points
bool comparePoints(cv::Point2f point1, cv::Point2f point2)
{
    if (point1.x < point2.x)
    {
        return true;
    }
    else
    {
        if ((point1.x == point2.x) && (point1.y < point2.y))
        {
            return true;
        }
    }

    return false;
}

void MarkersDetector::sortMarkers(std::vector<cv::Point2f> &markers)
{
    std::sort(markers.begin(), markers.end(), comparePoints);
}

【讨论】:

  • 这是一个使用比较函数在类中使用 std::sort 函数的简短示例,在本例中为 comparePoints 函数。
  • 您可以使用“编辑”按钮向您的答案添加信息,而不是发表评论。
【解决方案3】:

需要两件事:

  1. 由于sortByMarksExample 的成员,您需要告诉编译器正确的作用域,否则将找不到函数:

    sort(e, e, Example::sortByMarks);
    
  2. 然后有一个问题,因为sortByMarks 是一个普通的成员函数,而普通的成员函数需要一个隐藏的第一个参数,它是一个指向正在调用成员函数的实例的指针,它变成了this函数内部的指针。你可以通过制作成员函数static来解决这个问题:

    static bool sortByMarks(const Example &lhs, const Example &rhs);
    

还有第三个问题,那就是std::sort 函数实际上并不会排序 任何东西。您调用它的方式是告诉它对大小为 zero 的数组进行排序。


老实说,我认为您没有彻底解决问题。我猜你真正想要的是几个对象,每个对象都包含一个单个标记,然后对包含该标记的对象向量进行排序。

类似

class Example
{
private:
    int mark;

public:
    Example(int m) : mark(m) {}

    int get_mark() const { return mark; }
};

bool operator<(const Example& e1, const Example& e2)
{
    return e1.get_mark() < e2.get_mark();
}

std::vector<Example> example_vector = {
    Example(5),
    Example(1),
    Example(3)
};

std::sort(std::begin(example_vector), std::end(example_vector));

【讨论】:

  • 我已经用 init 函数编辑了这个问题。通过添加范围分辨率,我能够调用该函数。谢谢。但是,它似乎没有执行排序:(我还是做错了什么吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-18
  • 2017-11-09
  • 1970-01-01
  • 2013-07-01
  • 1970-01-01
相关资源
最近更新 更多