首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

关于 STL的map的find方法为什么找不到确又追加不进去,该怎么处理

2012-02-28 
关于 STL的map的find方法为什么找不到确又追加不进去typedefstruct_gpc_vertex/*Polygonvertexstructure*/

关于 STL的map的find方法为什么找不到确又追加不进去
typedef   struct   _gpc_vertex                                           /*   Polygon   vertex   structure                     */
{
    double                             x;                         /*   Vertex   x   component                                 */
    double                             y;                         /*   vertex   y   component                                 */
    bool   operator   <   (const     _gpc_vertex   &p2)   const
    {
    if   (fabs(x-p2.x   )   <   0.001   &&   fabs(y   -   p2.y   )   <   0.001)
    {
    return   false;
    }
    if   (x   <   p2.x)
    {
    return   true;
    }
    if   (fabs(x   -   p2.x)   <   0.001)
    {
    return   y   <   p2.y;
    }
    return   false;
    }
}   gpc_vertex;

gpc_vertex   vert;
vert.x   =   pt.x;
vert.y   =   pt.y;
std::map <gpc_vertex,   LPstruPolygonVert> ::iterator   iter   =     m_mapPoints.find(vert);
LPstruPolygonVert   pVert   =   NULL;
if   (iter   ==   m_mapPoints.end())
{

if   (FindPoint(pt))
{
AcDbObjectId   idd;
CreateCircle(pt,3.0,6,idd);
ads_point   pp;
acedGetPoint(NULL, "\n出现矛盾了。。这个找到了 ",pp);
}

pVert   =   new   struPolygonVert();
pVert-> pt   =   pt;
m_Verts.Add(pVert);

std::pair <std::map <gpc_vertex,   LPstruPolygonVert> ::iterator,bool>   pSuc;

pSuc   =     m_mapPoints.insert(std::pair <gpc_vertex,   LPstruPolygonVert> (vert,pVert));

if   (pSuc.second   ==   false)
{
AcDbObjectId   idd;
CreateCircle(pt,2.0,5,idd);
ads_point   pp;
acedGetPoint(NULL, "\n出现错误了,没有找到也加不进去。。 ",pp);
}


m_Verts.GetSize();


return   pVert;
}
else
{
pVert   =   iter-> second;
return   pVert;
}

[解决办法]
operator <逻辑有问题,比如 a(1,2) 和 b(1.0001,1) 相比较,a <b,同时 b <a。
看出来了吧
[解决办法]
#include <iostream>
#include <map>
#include <iterator>
using namespace std;

struct My_Point
{
int x;
int y;
My_Point(const int &_x=0,const int &_y=0):x(_x),y(_y){}


inline
bool operator <(const struct My_Point &rhs)const
{
if(x <rhs.x)return true;
else if(x> rhs.x)return false;
else return y <rhs.y;
}
inline
bool operator==(const struct My_Point &rhs)const//要定义KEY==
{
return (x==rhs.x)&&(y==rhs.y);
}
};

int main()
{
map <My_Point,string> m_map;
typedef map <My_Point,string> ::iterator ITER;

m_map.insert(make_pair(My_Point(1,1), "第1个点 "));
m_map.insert(make_pair(My_Point(2,2), "第2个点 "));
m_map.insert(make_pair(My_Point(3,1), "第3个点 "));
m_map.insert(make_pair(My_Point(1,4), "第4个点 "));
m_map.insert(make_pair(My_Point(1,2), "第5个点 "));
m_map.insert(make_pair(My_Point(6,1), "第6个点 "));

ITER it=m_map.find(My_Point(3,1));
if(it!=m_map.end())
{
cout < <it-> second < <endl;//找到了
}
m_map.erase(it);//删除
for(it=m_map.begin();it!=m_map.end();++it)
{
cout < <it-> first.x < < ", " < <it-> first.y < < "\t ";
cout < <it-> second < <endl;
}

it=m_map.find(My_Point(2,5));
if(it==m_map.end())
{
cout < < "没找到 " < <endl;
}
m_map.insert(make_pair(My_Point(2,5), "后来插入的点 "));//插入之
//放假在家.手边没书.我记得MULTIMAP才返回pair <it,bool>
//map只返回it
//记不大清了.

for(it=m_map.begin();it!=m_map.end();++it)
{
cout < <it-> first.x < < ", " < <it-> first.y < < "\t ";
cout < <it-> second < <endl;
}

system( "PAUSE ");
return 0;

}

[解决办法]
说过了,你的operator <不对。再改。
[解决办法]
因为你的比较运算逻辑有问题,所以map内部的红黑树处在一个错误状态。find和insert恰巧沿不同路径进行了搜索。
[解决办法]
operator <必须是严格弱序,这在标准中有说明.
对于小于比较,严格弱序意味着下面的等价关系:
(a < b) <==> !(b < a)
( a < b && b < c) <==> a < c;

很显然,你的fabs(x-p2.x ) < 0.001这种判断破坏了严格弱序:
假设y都一样,设p2.x = p1.x + 0.0009, p3.x = p2.x + 0.0009,借助p2,可以推出p3 == p1 的结论,而直接比较p1和p3,却有p1 <p3。因此,你需要修改operator <或者规格化数据,确保不出现这种矛盾。
[解决办法]
< 最好保留它本身纯粹的数学意义,否则很容易带来各方面的问题。你的问题最好是从规格化数据入手,比如在你的 <关系中0.001是一个threshold,那么在对这个结构的初始化以及使用中,两个数据的x,y差值小于0.001都是没有意义的。在结构定义中加入这种约束,使得任何结构中的x,y之差都不会小于0.001

热点排行