我的程序中有一个 std::map 存储值对。我希望 map 中的键是唯一的——这是 std::map 类的预期行为。但是当我将对插入其中时,一些键会重复。我该如何解决这个问题?
我的代码如下:
map<float,vector<float> *> inpDataMap;
inpDataMap.clear();
for(int i = 0; i < input.getNum(); i++)
{
float xVal = input[i][0];
float yVal = input[i][1];
if(inpDataMap.count(xVal) > 0)
{
myfile << i << " repeated xval: " << xVal << " : " << yVal << endl;
inpDataMap[xVal]->push_back(yVal);
myfile << "repeated value pushed" << endl;
}
else
{
vector<float> *inVec = new vector<float>;
inVec->push_back(yVal);
inpDataMap[xVal] = inVec;
myfile << i << " not repeated:" << xVal << ":" << yVal << endl;
}
}
如您所见,我这里的 map 实际上是一个 float 和相关 float vector 的关联。如果已经存在一个键,则将该值添加到与该键对应的 vector 中。但正如我所说, key 不是唯一存储的。谁能帮我解决这个问题?
拉克什。
最佳答案
float 的问题是你不能简单地使用==
运算符以确保它们相等。例如,一个数字可能是 7.0
但另一个实际上可以是7.000000000015
,即使它应该是 7.0
以及。
方法是定义一个精度,您希望将这些精度与这些 float 进行比较,并检查它们的差异是否小于精度。对于给定的示例,如果我们选择精度 0.000001
,这两个数字相等,因为 | (7.000000000015 - 7.0)| < 0.000001.
您可以通过自己的比较器实现这种逻辑。 std::map
有一个比较器类作为其模板参数之一。
更新:
事实证明,确实没有解决映射中浮点键问题的通用方法。评论中概述的问题非常严重。 map 比较器需要保证所插入键的严格弱排序,但对于 float 的一般情况似乎不可行。
假设您要插入 3 个键:a、b 和 c。有可能 a < b
是假的(因为它们在给定的精度下是相等的),b < c
是错误的(出于与 a < b
相同的原因),但 a 和 c 可能彼此“远离”,即 a < c
将返回 true(它们不相等),这很糟糕。
要克服这个问题,您需要对预期的 key 有一些了解。如果它们之间的距离足够远(距离大于通常的浮点运算错误),则可以编写一个合适的比较器。
有关比较器的示例,您可以转到 https://stackoverflow.com/a/6684830/276274
关于c++ - 键在 C++ 映射中不是唯一的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12930967/