如何将struct更新为map中的键

时间:2016-09-24 03:10:19

标签: c++ struct

我一直在努力使用地图,我在地图中使用struct作为键 问题出在这一部分:

void display(const std::map<ChildInfo, unsigned int>& counts, std::vector<ChildInfo>& v) {
    ChildInfo infoUpdate;

    for (auto count = counts.begin(); count != counts.end(); ++count) {
        std::cout << "Value " << count->first << " has count " << count->second << std::endl;
//      counts[infoUpdate.gram] = infoUpdate.gram / count->second;
    }
}

我应该怎么做才能将巧克力克重复一次?

这是我的代码:

2 个答案:

答案 0 :(得分:0)

您无法更改地图中的密钥,因为这可能会破坏所需的排序顺序。如果您需要这样做,您需要从地图中删除密钥(和值),更新它,然后将其重新插入。

ChildInfo的排序键不正确,就好像两个ChidInfos具有相同的克,排序顺序是不确定的。如果第一个比较(gram)相等,你需要在比较中添加另一个检查来比较其他东西(ids)。

答案 1 :(得分:0)

我认为你使用错误的map来解决问题。

让我们说有三个孩子有1公斤巧克力。如果我理解正确的话,你想在三者之间划分1公斤。这使我认为地图的关键是1kg,它应该映射到一组三个孩子。

std::map<double, std::set<ChildInfo>>

使用double作为密钥很棘手,因为比较不如整数类型的比较可靠。您可以使用自定义比较功能来测试某个容差范围内的数字。

这是一个工作计划:

#include <iostream>
#include <algorithm>
#include <vector>
#include <map>
#include <set>

using namespace std;

struct ChildInfo
{
   int id;
   double gram;
};

// Custom functor to compare doubles.
struct DoubleCompare
{
   bool operator()(double x1, double x2)
   {
      static double tolerance = 1.0E-10;  // Pick something else if this doesn't work.
      // If the numbers are almost equal.
      return ( fabs(x2-x1) > tolerance && x1 < x2);
   }
};

// Function to compare two ChildInfo to insert them into a set.
bool operator < (const ChildInfo& lhs, const ChildInfo& rhs) { return lhs.id < rhs.id; }

std::ostream& operator<<(std::ostream& str, const ChildInfo& ci) {
   str << " " << ci.id << " gram " << ci.gram << "\n";
   return str;
}

// Read the info for one child.
void input(vector<ChildInfo> &v)
{
   ChildInfo newInfo;

   cin >> newInfo.id >> newInfo.gram;
   v.push_back(newInfo);   
}

// Compute the mapped info from the vector of ChildInfo
void computeMappedInfo(vector<ChildInfo> const& vinfo,
                       std::map<double, std::set<ChildInfo>, DoubleCompare>& mappedInfo)
{
   // Separate them into sets first.
   for ( ChildInfo const& info : vinfo )
   {
      mappedInfo[info.gram].insert(info);
   }

   // Divide the grams in the set.
   for ( auto& item : mappedInfo )
   {
      // The set can't be changed in place.
      // Create a new set and replace the old set with the new set.

      std::set<ChildInfo> newSet;
      size_t s = item.second.size();
      for ( auto info : item.second )
      {
         info.gram /= s;
         newSet.insert(info);
      }
      mappedInfo[item.first] = newSet;
   }
}

// Display the mapped info.
void display(std::map<double, std::set<ChildInfo>, DoubleCompare> const& mappedInfo)
{
   for ( auto const& item : mappedInfo )
   {
      for ( auto& info : item.second )
      {
         std::cout << info << std::endl;
      }
   }
}

int main()
{
   int childNum = 0;
   cin >> childNum;

   std::vector <ChildInfo> info;

   for (int i = 0; i < childNum; ++i) {
      input(info);
   }

   std::map<double, std::set<ChildInfo>, DoubleCompare> mappedInfo;
   computeMappedInfo(info, mappedInfo);
   display(mappedInfo);

   return 0;
}

输入:

8
1 1000
2 1000
3 1000
4 500
5 600
7 800
8 800

输出:

 4 gram 500

 5 gram 600

 7 gram 400

 8 gram 400

 1 gram 333.333

 2 gram 333.333

 3 gram 333.333

http://ideone.com/Nq5XBH处查看它。