我应该如何比较指针对(对于排序谓词)

时间:2010-04-23 15:08:45

标签: c++ stl sorting

我有一个装满数十亿以下物品的STL容器

pair<SomeClass*, SomeClass*>

我需要以下形式的一些功能

/*returns items sorted biggest first */

bool sortPredicate (pair<SomeClass*, SomeClass*>two,  pair<SomeClass*, SomeClass*> one)
{
  return ???;
}

我可以使用一些技巧来快速比较指针对吗?

编辑1:澄清

最后我只想对指针对列表进行排序,使所有重复项彼此相邻。假设SomeClass中没有明确的方法可用于此目的 - 我只有指针对,我想找到所有相同的对(并行)。我认为有一种方法可以解决这个问题,但是如果你能想到更好的并行方法,请告诉我。

编辑2:澄清

修复了我的代码(排序谓词的参数错误 - 它们应该成对)。

4 个答案:

答案 0 :(得分:9)

C ++的一个怪癖是,相同类型的任意指针不一定(必然)与&lt;相比,但与std::less相当。

不幸的是,operator<的{​​{1}}是根据组件std::pair定义的,而不是operator<

因此,假设您希望两个对落在相同的排序位置,当且仅当它们指向相同的两个对象时,您需要:

std::less

在几乎任何你可以命名的系统上,这应该编译为与// "less than" template<typename T> bool lt(const T &lhs, const T &rhs) { return std::less<T>()(lhs, rhs); } typedef std::pair<SomeClass*, SomeClass*> mypair; bool sortPredicate(const mypair &lhs, const mypair &rhs) { return lt(lhs.first, rhs.first) || (!lt(rhs.first, lhs.first) && lt(lhs.second, rhs.second)); } 相同的代码,但这不正式。如果指针的referands是同一个对象的所有子对象(例如,如果你有一个巨大的数组,并且所有对都指向那个数组的元素),那么return lhs < rhs;对于指针是可以的,因此可以operator<

如果你想成对并且只有当他们指向的对象排序相同的时候才会对同一个排序位置进行配对,那么你需要添加额外的解引用:

std::pair<pointer,pointer>

如果允许的话,也许您还会添加对空指针的检查。当然,如果您知道SomeClass确实是类类型而不是指针类型,那么您不需要在上面的版本中使用bool sortPredicate(const mypair &lhs, const mypair &rhs) { return lt(*lhs.first, *rhs.first) || (!lt(*rhs.first, *lhs.first) && lt(*lhs.second, *rhs.second)); } ,只需为SomeClass定义std::less并且:

operator<

您可能会或可能无法对该位进行优化,因为在对lessptr的第一次和第二次调用中都执行了一些重复的空值检查。如果您非常关心,请查看编译器使用它做什么。

答案 1 :(得分:4)

假设您的班级有比较运算符:

bool sortPredicate (SomeClass *two,  SomeClass *one)
{
  return *two > *one;
}

如果您只想比较指针地址,请使用std::greater<T>

sort(container.begin(), container.end(), std::greater<SomeClass *>());

编辑:好的,我真的不知道你现在要做什么,最近的编辑。如果您只想查找重复项,为什么不使用默认排序?

答案 2 :(得分:0)

如果我理解正确你的谓词应该有以下签名

bool sortPredicate(pair<SomeClass*, SomeClass*>& lhs, pair<SomeClass*, SomeClass*>& rhs);

我对你的课程一无所知,如果它有任何自然顺序,那么很难猜出你想如何对它进行排序。在评论中你写的最重要的项目应该是第一个。我假设有&lt;班级的操作员。怎么样?

bool sortPredicate(pair<SomeClass*, SomeClass*>& lhs, pair<SomeClass*, SomeClass*>& rhs)
{
    if(!(*(lhs.first) < *(rhs.first) || *(rhs.first) < *(lhs.first))) // If there is == operator use it.
    {
        return *(rhs.second) < *(lhs.second);
    }
    else
    {
        return *(rhs.first) < *(lhs.first);
    }

}

编辑: Ok thx澄清。怎么样?

bool sortPredicate(pair<SomeClass*, SomeClass*>& lhs, pair<SomeClass*, SomeClass*>& rhs)
{
    if(lhs.first == rhs.first)
    {
        return rhs.second < lhs.second;
    }
    else
    {
        return rhs.first < lhs.first;
    }
}

答案 3 :(得分:0)

您应该在对类上定义operator<。我假设您的一对持有item1item2。所以:

template <class T>
class pair{
private:
  T item1;
  T item2
public:
  // [...] other stuff goes here
  // here the comparing
  bool operator<(pair p){
    return (item1 < p.item1 || (item1 == p.item1 && item2 < p.item2));
  }
};

此解决方案假定项目已定义<==运算符。

我认为我没有达到您正在寻找的内容,但我建议您在对类中重载<>==运算符。