如何在map中将struct更新为键

How to update struct as a key in map

本文关键字:更新 struct 中将 map      更新时间:2023-10-16

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

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

我该怎么做才能把巧克力克除以重复数?

这是我的代码:

我想你用错了map来解决你的问题。

假设有三个孩子有1kg巧克力。如果我没理解错的话,你是想把1kg分给三个人。这让我想到映射的键是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

不能更改映射中的键,因为这可能会破坏所需的排序顺序。如果需要这样做,则需要从映射中删除键(和值),更新它,然后将其插入。

您的ChildInfo的排序键不正确,如果两个ChildInfo具有相同的gram,则排序顺序不确定。您需要在比较中添加另一个检查,如果第一个比较(gram)相等,则将比较其他内容(id)。