【问题标题】:std::map with string or struct key带有字符串或结构键的 std::map
【发布时间】:2019-02-08 09:08:44
【问题描述】:

如何在 c++ 中内存映射结构或字符串类型的键值的 std:map? 有可能这样做吗?现在我正在使用具有键值 int 的映射进行内存映射,但是由于 int 的最大范围是有限的,并且我的程序中键值的最大大小约为 10^24,所以我被卡住了。那么通过使用键类型作为结构或字符串我可以解决这个问题吗?

 int p0, p1, p2;
map<int,int> p0obj, p1obj, p2obj, size_p; int count = 0; 

                    float d0, d1, d2;                      
                    float a0 = a[p0];  
                    float b0 = b[p0]; 
                    float a1 = a[p1]; 
                    float b1 = b[p1];
                    float a2 = a[p2]; 
                    float b2 = b[p2];
                    if(d0>0 && d1>0 && d2>0) {
                        int key = d0+max_d*(d1+max_d*(d2+max_d*(a0+max_c*(b0+max_c*(a1+max_c*(b1+max_c*(a2+max_c*b2)))))));
        //std::string key = std::to_string(k);
                        p0obj[key] = p0; p1obj[key] = p1; p2obj[key] = p2; size_p[key]++;
                        oa << p0obj; oa << p1obj; oa << p2obj; oa << size_p;
                        std::cout<<"key="<<key<<std::endl;
                    }
                } 
            } 

【问题讨论】:

  • 在您的代码中,键类型是std::string,您是说代码不起作用(如果是,那么如何),还是您的意思是 value 类型不是 key 输入你的问题?在您的代码中,值类型是int
  • 我没有尝试以字符串为键运行。我想知道 key 中的 string 或 struct 是否有效。
  • 请不要使用“memory mapping”这个词,它有非常不同的语义。你应该使用你的结构作为关键,并定义一个正确的operator&lt;
  • 您能否将您实际遇到的问题简化为minimal reproducible example?它似乎隐藏在所有不相关的算术中(顺便说一句,sqrt() 是什么意思,std::hypot() 会更好吗?)
  • 这不是内存映射文件的代码,您在混淆您的术语。这只是将数据结构序列化为文件。

标签: c++ boost-serialization


【解决方案1】:

您似乎想使用一堆floats 作为地图中的键。

您可以通过将它们包装为 tuple 或定义更有意义的 struct 类型来做到这一点:

#include <map>

struct MyKey {
    float d0, d1, d2, a0, b0, a1, b1, a2, b2;

    bool operator < (const MyKey& o) const {
        return std::tie(d0, d1, d2, a0, b0, a1, b1, a2, b2) < std::tie(o.d0, o.d1, o.d2, o.a0, o.b0, o.a1, o.b1, o.a2, o.b2);
    }
};

struct MyValue {
    float p0, p1, p2;
};

std::map<MyKey, MyValue> pobj;

要插入此地图:

    pobj.insert({{d0, d1, d2, a0, b0, a1, b1, a2, b2}, {p0, p1, p2}});

但不确定你会用这样的地图做什么。通过浮点数搜索可能效果不佳。但是用例如查找子空间lower_bound 可能仍然有用。

    auto it = pobj.lower_bound({d0, d1, d2, a0, b0, a1, b1, a2, b2});
    if (it != end(pobj)) {
        const MyKey& key = it->first;
        const MyValue& value = it->second;
        std::cout << "found: " << value.p0 << " " << value.p1 << " " << value.p2 << std::endl;
    }

【讨论】:

  • 可能值得一提的是floats 很少相等,因此为“相同”键添加值可能会出错
  • @DineshLama - 查看我的编辑。使用find,但更好的是lower_boundupper_bound,因为find 需要完全匹配(使用浮点数很难实现)。
  • 实际上也可以用它们来代替float int。如果我将 float 更改为 int,我应该更改上面的任何行吗?
  • 在键中使用整数而不是浮点数是一个非常好的主意,因为您不必在搜索过程中处理不精确的比较。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-12-12
  • 1970-01-01
  • 2021-09-19
  • 1970-01-01
  • 2015-07-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多