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;
        }

    }

ご覧のとおり、ここにあるマップは、実際にはフロートと関連付けられたフロートのベクトルの関連付けです。すでにキーが存在する場合、そのキーに対応するベクトルに値が追加されます。しかし、私が言ったように、キーは一意に保存されません。誰かが私がこの問題を解決するのを手伝ってくれる?

Rakesh。

4

3 に答える 3

9

フロートの問題は、単に==演算子を使用してそれらが等しいことを確認できないことです。たとえば、ある番号はあるかもしれませんが7.0、別の番号は実際7.000000000015にはそうであるはずでしたが、実際にはそうなる可能性が7.0あります。

次に、これらの浮動小数点数を比較する精度を定義し、それらの差が精度よりも小さいかどうかを確認します。与えられた例では、精度を選択すると0.000001、これら2つの数値は等しくなります。| (7.000000000015 - 7.0)| < 0.000001.

この種のロジックは、独自のコンパレータを介して実装できます。std::mapテンプレート引数の1つとしてコンパレータクラスがあります。

アップデート:

マップ内の浮動小数点キーの問題を解決する一般的な方法は実際にはないことが判明しました。コメントで概説されている問題は非常に深刻です。マップコンパレータは、挿入されるキーの厳密な弱い順序を保証する必要がありますが、フロートの一般的なケースでは実行可能ではないようです。

a、b、cの3つのキーを挿入するとします。a < bfalse(指定された精度で等しいため)、b < cfalse(と同じ理由)である可能a < b性がありますが、aとcが互いに「遠く」離れている可能性があり、a < ctrueを返します(これらは等しくない)、これは悪いことです。

それを乗り越えるには、予想されるキーについてある程度の知識が必要です。それらが互いに十分に離れている場合(距離が通常の浮動小数点演算エラーよりも大きい場合)、適切なコンパレーターを作成できます。

コンパレータの例については、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

std::vectorへのポインタの代わりに a を保存するのはどうですか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 に答える