2017-03-02 4 views
0

J'ai un code qui ressemble à peu près à ceci; étant donné deux cartes, si la clé first existe dans les deux cartes, alors multipliez les deux valeurs second ensemble, puis additionnez tous les produits. Par exemple:Exécuter une fonction sur des paires dans une carte

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

La réponse devrait être 2.5*10.0 + 0.5*20.0, la somme des produits des clés correspondantes.

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

Je voudrais factoriser cela et std::set_intersection semble être proche de ce que je veux que la documentation a an example using std::back_inserter, mais est-il un moyen d'obtenir que cela fonctionne sur les cartes et éviter le tableau intermédiaire?

+0

Vérifiez vos déclarations d'objet de jeu. Il semble que vous voulez dire std :: pair comme argument de template. –

+0

Également un mot sur ce que vous attendez exactement à chaque fois que vous trouvez une paire. Et chaque fois que vous ne le faites pas. – tinstaafl

+0

@tinstaafl J'ai ajouté du texte qui décrit ce que j'essaie de faire. –

Répondre

2

Le code que vous utilisez est déjà très proche de la façon dont set_intersect serait implémenté. Je ne vois aucun avantage à créer une nouvelle carte et à la parcourir.

Cependant, il y avait quelques choses avec votre code que je voulais mentionner.

Si vous allez incrémenter vos itérateurs, vous ne devriez pas les rendre constants.

Je m'attendrais à ce qu'il y ait plus d'échecs que de coups lors de la recherche d'éléments équivalents. Je suggère d'avoir le moins de comparaisons d'abord:

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

L'itérateur 'const' était une faute de frappe, désolé. En regardant les chiffres, le nombre moyen de fois autour de la boucle est d'environ 1000 par appel, avec seulement 1% étant des correspondances, alors je vais essayer votre suggestion. –