如何使用std :: map将bool映射到3d点结构?

时间:2011-05-24 11:05:27

标签: c++ map

如何使用以下结构:

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

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

6 个答案:

答案 0 :(得分:18)

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

3-ary元组的典型方法如下:

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相同,那么你就可以比较y了。如果它们相同,那么同样地,您将进入z比较。

答案 1 :(得分:6)

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

更新在此处添加全包式的“吃蛋糕,吃得太多 - 无瑕疵”的解决方案。恕我直言,它摇滚!

#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:

编译器能够有效地优化整个程序...... return 0。这很漂亮。


这是一个简单的答案:

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 :: lexicographical_compare

#include <algorithm>

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

答案 2 :(得分:1)

一种懒惰的方式:

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

答案 3 :(得分:0)

最简单的写法是这样的:

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;

}

答案 4 :(得分:0)

如果它们应该以某种方式排序,你需要指定那种确切的方式(例如,距离0/0/0的欧几里德距离)。如果您只想区分不同的点,您可以执行类似

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

答案 5 :(得分:-1)

猜猜伙计们,

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

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