【发布时间】:2014-01-14 15:45:56
【问题描述】:
要求:
- 基于数字比较键(例如 std::map)对自身进行排序的容器
- 根据浮点容差检查键是否存在(例如 map.find() 并使用自定义比较器)
- 还有一个棘手的问题:比较器使用的浮点容差可能会由用户在运行时更改!
前两个可以使用带有自定义比较器的地图来完成:
struct floatCompare : public std::binary_function<float,float,bool>
{
bool operator()( const float &left, const float &right ) const
{
return (fabs(left - right) > 1e-3) && (left < right);
}
};
typedef std::map< float, float, floatCompare > floatMap;
使用此实现,floatMap.find(15.0001) 将在地图中找到 15.0。
但是,假设用户不希望浮动容差为 1e-3。 使此比较器功能在运行时使用可变容差的最简单方法是什么?我不介意每次更新 epsilon 时根据新的比较器重新创建和重新排序地图。
【问题讨论】:
-
您必须使用新的排序标准创建一个新地图,并使用旧地图中的元素填充它。但是您认为您的比较器满足严格的弱排序吗?这是一项要求,否则您的地图就会损坏。
-
这样的比较器是行不通的:关联容器需要严格的排序。您应该能够使用默认排序获得所需的内容,使用
lower_bound(两次,对于公差范围的每一端)而不是find。这也给出了您的第三个要求,因为您可以为每次查找指定容差。 -
排序比较器与容错搜索比较器没有太大关系!
-
要了解为什么严格排序很重要,请考虑将值 14.9991、15.0 和 15.0009 插入到您的地图中。根据插入顺序,您最终可能会得到 1 个或 2 个条目。搜索也可能会失败,但这更难证明。
-
“在某些情况下未定义”表示您的地图不能保证正常工作。在我的书中,这意味着它已经坏了。
标签: c++ map stl floating-point