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

发布于 2024-08-30 00:47:21 字数 576 浏览 1 评论 0原文

我有一个 STL 容器,里面装满了数十亿个以下对象

pair<SomeClass*, SomeClass*>

我需要以下形式的一些函数

/*returns items sorted biggest first */

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

是否有一些技巧可以用来非常快速地比较指针对?

编辑1:澄清

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

编辑2:澄清

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

I have a STL container full of billions of the following objects

pair<SomeClass*, SomeClass*>

I need some function of the following form

/*returns items sorted biggest first */

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

Is there some trick I can use to very quickly compare pairs of pointers?

Edit 1: A clarification

In the end I just want to sort the list of pointer-pairs such that all of the duplicates are next to each other. Assume that there is no clear method in SomeClass that can be used for this purpose---I only have pointer pairs, and I want to find all identical pairs (in parallel). I thought a sort would do the trick, but if you can think of a better parallel method, let me know.

Edit 2: A clarification

Fixed my code (the arguments to the sort predicate were wrong--they should be pairs).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

心头的小情儿 2024-09-06 00:47:21

C++ 的一个怪癖是,相同类型的任意指针并不(必然)与 < 进行比较,而是与 std::less 进行比较。

不幸的是,std::pairoperator< 是根据组件上的 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));
 }

在您可以命名的几乎任何系统上,这应该编译为与 相同的代码返回 lhs < rhs;,但这在形式上并不正确。如果指针的引用对象都是同一对象的子对象(例如,如果您有一个巨大的数组,并且所有对都指向该数组的元素),则对于指针来说,operator< 是可以的因此对于 std::pair 来说是可以的。

如果您希望配对落在相同的排序位置,当且仅当它们指向的对象排序相同时,那么您需要添加额外的取消引用:

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<< /code> 对于 SomeClass 和:

inline bool lessptr(const SomeClass *lhs, const SomeClass *rhs) {
    if (lhs == 0) return rhs != 0;
    if (rhs == 0) return false;
    return *lhs < *rhs;
}

bool sortPredicate(const mypair &lhs, const mypair &rhs) {
    return lessptr(lhs.first, rhs.first) 
        || (!lessptr(rhs.first, lhs.first) && lessptr(lhs.second, rhs.second));
 }

您可能能够也可能无法稍微优化它,因为在第一次和第二次调用 lessptr 时都会执行一些重复的空检查。如果您很关心,请看看编译器如何处理它。

It is a quirk of C++ that arbitrary pointers of the same type are not (necessarily) comparable with <, but are comparable with std::less.

Unfortunately, the operator< for std::pair is defined in terms of operator< on the components, not std::less.

So, assuming that you want two pairs to fall in the same sort position if and only if they point to the same two objects, you need:

// "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));
 }

On pretty much any system you can name, this should compile to the same code as return lhs < rhs;, but that is not formally correct. If the referands of the pointers are all subobjects of the same object (for instance if you have a huge array and all the pairs point to elements of that one array), then operator< is OK for the pointers and hence OK for std::pair<pointer,pointer>.

If you want to pairs to fall in the same sort position if and only if the objects they point to sort the same, then you'd add the extra dereference:

bool sortPredicate(const mypair &lhs, const mypair &rhs) {
    return lt(*lhs.first, *rhs.first) 
        || (!lt(*rhs.first, *lhs.first) && lt(*lhs.second, *rhs.second));
 }

and perhaps you'd also add checks for null pointers, if those are permitted. Of course if you know that SomeClass really is a class type, not a pointer type, then you don't need to use std::less in the version above, just define operator< for SomeClass and:

inline bool lessptr(const SomeClass *lhs, const SomeClass *rhs) {
    if (lhs == 0) return rhs != 0;
    if (rhs == 0) return false;
    return *lhs < *rhs;
}

bool sortPredicate(const mypair &lhs, const mypair &rhs) {
    return lessptr(lhs.first, rhs.first) 
        || (!lessptr(rhs.first, lhs.first) && lessptr(lhs.second, rhs.second));
 }

You may or may not be able to optimise that a bit, since there are some repeated null checks performed in both the first and second calls to lessptr. If you care that much, see what the compiler does with it.

稍尽春風 2024-09-06 00:47:21

假设您的类有比较运算符:

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

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

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

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

Assuming your class has comparison operators:

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

If you just want to compare the pointer addresses, use std::greater<T>:

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

EDIT: OK, I really have no idea what you are trying to do now, with your most recent edit. Why not just use the default sort, if all you want to do is find duplicates?

一场春暖 2024-09-06 00:47:21

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

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

我对您的类一无所知,也不知道它是否有任何自然顺序,因此很难猜测您想要如何对其进行排序。在评论中,您写道最大的项目应该放在第一位。我假设有 <类的运算符。这个怎么样?

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);
    }

}

编辑:好的,谢谢您的澄清。这个怎么样?

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;
    }
}

If I understand correctly Your predicate should have the following signature

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

I know nothing about Your class and if there is any natural order for it, so it's hard to guess how You want to sort it. In The comment You write that the biggest items should be first. I assume there is < operator for the class. How about this?

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);
    }

}

EDIT: Ok thx for clarifying. How about this?

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;
    }
}
丑丑阿 2024-09-06 00:47:21

您应该在您的pair类上定义一个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));
  }
};

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

我想我没有满足您正在寻找的内容,但我建议重载 <>==你的pair类中的运算符。

You should define an operator<on your pair class. I assume that your pair holds item1 and item2. So:

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));
  }
};

This solution assumes that the items have defined the < and the == operators.

I suppose I didn't meet what you were exactly looking for, but I recommend to overload the <, >, and == operators in your pair class.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文