簡體   English   中英

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

[英]keys not unique in c++ map

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

    }

正如您所看到的,我在這里的地圖實際上是一個浮動關聯浮點數的關聯。 如果已存在密鑰,則將該值添加到與該密鑰對應的向量中。 但就像我說的那樣,密鑰並不是唯一存儲的。 有人可以幫我解決這個問題嗎?

拉克什。

浮點數的問題是你不能簡單地使用==運算符來確保它們是相等的。 例如,一個數字可能是7.0但另一個數字實際上可能是7.000000000015 ,即使它也應該是7.0

要做的是定義一個精度,您希望用它來比較這些浮點數並檢查它們的差異是否小於精度。 對於給定的示例,如果我們選擇0.000001的精度,則這兩個數字相等,因為| (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(它們不相等),這是壞的。

要克服這一點,您需要了解預期的密鑰。 如果它們彼此足夠遠(距離大於通常的浮點運算誤差),則可以寫入適當的比較器。

有關比較器的示例,您可以轉到https://stackoverflow.com/a/6684830/276274

地圖不能包含重復的鍵。 你可能認為這是因為浮點精度 - 你看起來相等的一些值實際上是不同的。 要解決此問題,您可以將自定義Compare類與地圖一起使用,以將足夠近的浮點數視為相等:

map<float,vector<float> *, CustomCompare> inpDataMap;

如何存儲std::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);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM