5

我的程序中有一个 std::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;
        }

    }

正如你所看到的,我在这里的地图实际上是一个浮点数和一个相关浮点数的向量的关联。如果已经存在一个键,则将该值添加到与该键对应的向量中。但就像我说的,密钥不是唯一存储的。有人可以帮我解决这个问题吗?

拉克什。

4

3 回答 3

9

浮点数的问题在于您不能简单地使用==运算符来确保它们相等。例如,一个数字可能是7.0,但另一个数字实际上可能是7.000000000015,即使它应该7.0也是。

要走的路是定义一个精度,你想用它来比较这些浮点数,并检查它们的差异是否小于精度。对于给定的示例,如果我们选择 的精度0.000001,这两个数字是相等的,因为| (7.000000000015 - 7.0)| < 0.000001.

您可以通过自己的比较器来实现这种逻辑。std::map有一个比较器类作为其模板参数之一。

更新:

事实证明,确实没有解决地图中浮点键问题的通用方法。评论中概述的问题非常严重。映射比较器需要保证插入的键的严格弱排序,但是对于浮点数的一般情况似乎不可行。

假设您要插入 3 个键:a、b 和 c。有可能a < b是假的(因为它们在给定的精度下是相等的),b < c是假的(出于a < ba < c不相等),这很糟糕。

要克服这一点,您需要对预期的键有所了解。如果它们彼此距离足够远(距离大于通常的浮点算术误差),则可以编写适当的比较器。

有关比较器的示例,您可以转到https://stackoverflow.com/a/6684830/276274

于 2012-10-17T09:23:42.757 回答
5

地图不能包含重复的键。您可能认为这是因为浮点精度 - 某些在您看来相等的值实际上是不同的。要解决这个问题,您可以Compare在地图中使用自定义类来将足够接近的浮点数视为相等:

map<float,vector<float> *, CustomCompare> inpDataMap;
于 2012-10-17T09:22:07.730 回答
0

如何存储 astd::vector而不是指向的指针vector

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];
    inpDataMap[xVal].push_back(yVal);
}
于 2012-10-17T09:27:07.930 回答