【问题标题】:Sorting a vector of objects对对象向量进行排序
【发布时间】:2011-06-22 02:47:14
【问题描述】:

我有一个填充了一些顶点对象实例的向量,需要根据它的“x”和之后的“y”坐​​标对其进行排序。

顶点.h

#ifndef VERTEX_H
#define VERTEX_H 1

class Vertex
{
private:
  double __x;
  double __y;
public:
  Vertex(const double x, const double y);
  bool operator<(const Vertex &b) const;
  double x(void);
  double y(void);
};

#endif // VERTEX_H

顶点.cpp

#include "vertex.h"

Vertex::Vertex(const double x, const double y) : __x(x), __y(y)
{
}

bool Vertex::operator<(const Vertex &b) const
{
  return __x < b.x() || (__x == b.x() && __y < b.y());
}

double Vertex::x(void)
{
  return __x;
}

double Vertex::y(void)
{
  return __y;
}

运行.cpp

#include <algorithm>
#include <stdio.h>
#include <vector>

#include "vertex.h"

void prnt(std::vector<Vertex *> list)
{
  for(size_t i = 0; i < list.size(); i++)
    printf("Vertex (x: %.2lf y: %.2lf)\n", list[i]->x(), list[i]->y());
}

int main(int argc, char **argv)
{
  std::vector<Vertex *> list;
  list.push_back(new Vertex(0, 0));
  list.push_back(new Vertex(-3, 0.3));
  list.push_back(new Vertex(-3, -0.1));
  list.push_back(new Vertex(3.3, 0));

  printf("Original:\n");
  prnt(list);

  printf("Sorted:\n");
  std::sort(list.begin(), list.end());

  prnt(list);

  return 0;
}

我期望的输出是:

Original:
Vertex (x: 0.00 y: 0.00)
Vertex (x: -3.00 y: 0.30)
Vertex (x: -3.00 y: -0.10)
Vertex (x: 3.30 y: 0.00)
Sorted:
Vertex (x: -3.00 y: -0.10)
Vertex (x: -3.00 y: 0.30)
Vertex (x: 0.00 y: 0.00)
Vertex (x: 3.30 y: 0.00)

但我实际得到的是:

Original:
Vertex (x: 0.00 y: 0.00)
Vertex (x: -3.00 y: 0.30)
Vertex (x: -3.00 y: -0.10)
Vertex (x: 3.30 y: 0.00)
Sorted:
Vertex (x: 0.00 y: 0.00)
Vertex (x: -3.00 y: -0.10)
Vertex (x: -3.00 y: 0.30)
Vertex (x: 3.30 y: 0.00)

我不知道到底出了什么问题,有什么想法吗?

【问题讨论】:

  • 如何编译?您的操作double Vertex::x() const?
  • 请允许我欢迎您来到 StackOverflow,并提醒我们通常在这里做的三件事:1) 当您获得帮助时,请尝试在您的专业领域中回答问题 2)Read the FAQs 3)当你看到好的问答时,给他们投票using the gray triangles,因为系统的可信度是基于用户通过分享他们的知识而获得的声誉。还记得接受更好地解决您的问题的答案,如果有的话,by pressing the checkmark sign

标签: c++ sorting object vector


【解决方案1】:

您将Vertex * 存储在容器中,而不是Vertex。当您调用std::sort 时,您实际上是在对指针的值进行排序,而不是对项目本身进行排序。

如果您真的需要存储指针(我对此表示怀疑),您可以使用这样的解决方法(未经测试):

struct less_than_key {
    inline bool operator() (const Vertex*& v1, const Vertex*& v2) {
        return ((*v1) < (*v2));
    }
};
std::sort(list.begin(), list.end(), less_than_key());

【讨论】:

  • @Wanderson 那么你是如何解决这个问题的?您将 std::vector 更改为 std::vector 还是其他?
  • 添加了一个编辑来修复它而不将指针更改为非指针。我没有尝试编译,所以如果我犯了任何错误,请告诉我,以便我编辑。
【解决方案2】:

如果您不想自己编写所有这些类(并且违反双下划线规则!),您可以考虑只使用一个

std::vector< std::pair<float, float> >

并使用std::sort。默认情况下,对按字典顺序进行比较(这是您要求的),因此您不需要任何额外的代码。

【讨论】:

  • 我知道我可以使用 std::pair,但它是 Vertex 类的简化版本,完整的具有我需要的角度、距离和其他计算方法。关于双下划线规则,我会确保在以后的代码中应用它。
  • @Wanderson:很公平。如果您无法为这些转换和计算使用免费函数,那么您将不得不创建自己的类(尽管它很可能将对向量作为其主要数据成员并公开其比较运算符)。跨度>
【解决方案3】:

您正在排序指针,而不是实际的 Vertex 对象。试试这个:

std::vector<Vertex> list;
list.push_back(Vertex(0, 0);
list.push_back(Vertex(-3, 0.3);
...

即摆脱列表容器中的指针和对 push_back 的调用中的新指针。

【讨论】:

    【解决方案4】:

    您似乎出于某种原因想要对绝对值进行排序:
    试试这个:

    bool Vertex::operator<(const Vertex &b) const
    {
      return std::abs(__x) < std::abs(b.__x) || (std::abs(__x) == std::abs(b.__x) && std::abs(__y) < std::abs::(b.__y));
    }
    

    注意:当你是同一个类时,你不需要调用 b.x() 来获取另一个对象的成员。您可以访问其他成员。

    注意:不要在标识符中使用双下划线。最好不要在标识符前加上下划线。

    【讨论】:

    • 实际上我需要列表开头的最左边的顶点。那么,它不可能是绝对值。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-07-07
    • 2021-02-06
    • 1970-01-01
    • 1970-01-01
    • 2015-01-18
    • 1970-01-01
    • 2011-10-15
    相关资源
    最近更新 更多