密钥在c ++ map中不是唯一的

Rak*_*h K 2 c++ map c++-standard-library

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

    }
Run Code Online (Sandbox Code Playgroud)

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

拉克什.

Mak*_*zin 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 < b),但是a和c可能彼此"远",a < c它将返回true(它们将返回true)是不平等的,哪个是坏的.

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

有关比较器的示例,您可以转到/sf/answers/467938131/


Luc*_*ore 5

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

map<float,vector<float> *, CustomCompare> inpDataMap;
Run Code Online (Sandbox Code Playgroud)

  • 如果你这样做,你需要非常小心,你的自定义比较正确地实现了严格的弱比较.如果你把"足够接近"的价值视为平等,那么很容易弄错... (2认同)