如何使用std::map将布尔映射到三维点结构

How to map a bool to a 3d point struct with std::map?

本文关键字:三维 结构 映射 何使用 std map 布尔      更新时间:2023-10-16

如何使用以下结构:

struct point 
{
    int x;
    int y;
    int z;
};

作为std::map<point, bool>的密钥?我应该如何定义两点的operator<

std::map这样的标准库容器要求您的排序是"严格弱排序",因此在设计时必须非常小心。

三元元组的典型方法如下:

bool operator<(const point& other) const
{
   if (x != other.x)
       return (x < other.x);
   if (y != other.y)
       return (y < other.y);
   return (z < other.z);
}

这就像一个仅用于x的比较器,但不同的是,如果两个x s相同,则可以进行比较y s。如果它们相同,则同样可以进行z比较。

当然,boost::tuple<int,int,int>会使这完全没有必要。

更新在这里添加全包的"吃蛋糕就吃"无缺点解决方案。IMHO,太棒了!

#include <boost/tuple/tuple_comparison.hpp>
struct point 
{
    int x, y, z;
    point(int x, int y, int z) : x(x), y(y), z(z) {}
    bool operator<(const point& rhs) const 
    {
        return boost::tie(x, y, z) < boost::tie(rhs.x, rhs.y, rhs.z);
    }
};

关键在于:一切都优化了。编译:

int main()
{
    point a(1,2,3), b(3,2,1);
    bool lt = a<b;
    return lt?0:255;
}

使用g++-O2在组装中产生以下结果。

main:
.LFB1132:
        pushl   %ebp
        xorl    %eax, %eax
        movl    %esp, %ebp
        popl    %ebp
        ret
.LFE1132:

编译器能够优化整个程序以。。。CCD_ 9。这很整洁。


简单的答案是:

struct point 
{
    point(int x, int y, int z) 
        : x(x), y(y), z(z) {}
    int x;
    int y;
    int z;
    bool operator<(const point& rhs) const 
    {
        if (x<rhs.x) return true;
        if (x==rhs.x) 
        { 
            if (y<rhs.y) return true;
            if (y==rhs.y) return z<rhs.z;
        }
        return false;
    }
};

此外,我会考虑重新定义我的结构,允许使用std::dictiongraphical_compare

#include <algorithm>
// ...
bool operator<(const point& rhs) const 
{
    return std::lexicographical_compare(&xyz, &xyz+3, &rhs.xyz, &rhs.xyz+3);
}

一种懒惰的方法:

bool operator<( point const &pt ) const
{
    return ::boost::make_tuple(x,y,z) <
           ::boost::make_tuple(pt.x,pt.y,pt.z);
}

最简单的编写方法如下:

bool operator<(const point& p) const
{
    if(x < p.x)
    {
        return true;
    }
    else if(p.x < x)
    {
        return false;
    }
    if( y < p.y)
    {
        return true;
    }
    else if( p.y < y)
    {
        return false;
    }
    if( z < p.z)
    {
        return true;
    }
    else if(p.z < z)
    {
        return false;
    }
    return false;
}

如果它们应该以某种方式排序,则需要指定确切的方式(例如,通过从0/0/0开始的欧氏距离)。如果你只想区分不同的点,你可以做一些类似的事情

x == x2 ? (y == y2 ?  (z < z2) : y < y2) : x < x2 

只是猜测,伙计们,

bool operator<(const point& other) const
{
  return( memcmp( (void*) this, (void*) &other, sizeof(point)) < 0);
}

当然,顺序有点奇怪,因为x、y和z都是有符号的值,但这应该适合排序到std::map中,不是吗?