2017-03-02 2 views
0

私はこのようなコードをいくつか持っています。両方のマップにfirstキーが存在する場合は、2つのマップを与え、2つのsecond値を掛け合わせて、すべての積を合計します。例:マップ内のペアのマッチングで関数を実行

s1 = {{1, 2.5}, {2, 10.0}, {3, 0.5}}; 
s2 = {{1, 10.0},   {3, 20.0}, {4, 3.33}}; 

答えは一致するキーの積の合計である2.5*10.0 + 0.5*20.0である必要があります。私はこれをリファクタリングしてstd::set_intersectionしたい

double calcProduct(std::map<int, double> const &s1, std::map<int, double> const &s2) 
{ 
    auto s1_it = s1.begin(); 
    auto s2_it = s2.begin(); 

    double result = 0; 
    while (s1_it != s1.end() && s2_it != s2.end()) 
    { 
     if (s1_it->first == s2_it->first) 
     { 
      result += s1_it->second * s2_it->second; 
      s1_it++: 
      s2_it++; 
     } 
     else if (s1_it->first < s2_it->first) 
     { 
      s1_it = s1.lower_bound(s2_it->first); 
     } 
     else 
     { 
      s2_it = s2.lower_bound(s1_it->first); 
     } 
    } 
    return result; 
} 

は、ドキュメントがan example using std::back_inserterを持っているように私が欲しいものに近いように見えますが、これはマップ上で動作し、中間配列を避けるために取得する方法はありますか?

+0

セットオブジェクトの宣言を確認してください。テンプレート引数としてstd :: pairを意味するようです。 –

+0

マッチするペアを見つけるたびに、あなたが何をしようとしているか正確に何か言います。 – tinstaafl

+0

@tinstaafl私は何をしようとしているのかを記述したテキストを追加しました。 –

答えて

2

使用しているコードは既にset_intersectの実装方法に非常に近いです。私は新しいマップを作成し、そのマップを反復することに利点はありません。

しかし、私は言及したいコードのいくつかの事がありました。

イテレーターを増分する場合は、一定にしてはいけません。

同等の要素を探すときは、ヒットよりもミスが多くなることが予想されます。私は最初に比較するよりも少ないことをお勧めします:

double calcProduct(std::map<int , double> const &s1 , std::map<int , double> const &s2) 
{ 
    auto s1_it = s1.begin(); 
    auto s2_it = s2.begin(); 

    double result = 0; 
    while (s1_it != s1.end() && s2_it != s2.end()) 
    { 
     if (s1_it->first < s2_it->first) 
     { 
      s1_it = s1.lower_bound(s2_it->first); 
     } 
     else if(s2_it->first < s1_it->first) 
     { 
      s2_it = s2.lower_bound(s1_it->first); 
     } 
     else 
     { 
      result += s1_it->second * s2_it->second; 
      s1_it++; 
      s2_it++; 
     } 
    } 
    return result; 
} 
+0

'const'イテレータはタイプミスです。数字を見ると、コールの平均回数はコール1回あたり約1,000であり、一致するのは1%だけなので、あなたの提案を試してみます。 –

関連する問題