将Java LinkedHashMap转换为C ++ std :: map

时间:2017-07-06 22:14:18

标签: java c++ dictionary hashmap hashtable

我正在尝试将程序从Java移植到C ++,我似乎无法弄清楚如何将LinkedHashMap转换为std :: map。我无法更改LinkedHashMap但我不限于std :: map。我需要它来生成相同的键/值对,但订购/散列/其他任何不重要的事情。

要转换的Java代码:

List<Face> faces = new ArrayList<Face>(modelFull.faces.length);
Map<Point3D, Integer> map = new LinkedHashMap<Point3D, Integer>();
for (int i = 0; i < modelFull.faces.length; i++) {
    Face f = new Face(modelFull.faces[i]);
    faces.add(f);
    for (int k = 0; k < 3; k++) {
        Point3D p = f.pts[k];
        Integer v = map.get(p);
        if (v == null) {
            v = 0;
        }
        map.put(p, v + 1);
    }
}

我的尝试:

std::map<RVPoint3D, int> pointMap;
auto modelFaces = modelFull.getFaces();
for (const auto &face : modelFaces)
{
    Face newFace = Face(face);
    for (int k = 0; k < 3; ++k)
    {
        RVPoint3D pt = newFace.getPts()[k];
        ++pointMap[pt];
    }
    faces.push_back(newFace);
}

Java实现创建了一个大小为7523的映射,而C ++的映射为7967.两者共检查了45234个元素,因此它似乎正在通过潜在的密钥正确迭代。

我不知道从哪里开始。我已经尝试过载运算符,自定义比较器,自定义哈希函数等,我必须遗漏一些东西。

2 个答案:

答案 0 :(得分:0)

在新版地图项的java版本中,您将v设置为0,然后在将其放入地图时将1添加到其中。在C++版本中,您将其放入0

<强>爪哇

Integer v = map.get(p);
if (v == null) {
    v = 0;
}
map.put(p, v + 1); // new map entries go in as 1

<强> C ++

if (pointMap.count(pt))
{
    pointMap[pt] += 1;
} else {
    pointMap[pt] = 0; // new map entries go in as 0
}

您还可以在Java中设置null Iteger0吗?你不需要做类似的事情:

v = new Integer(0); // ? 

旁注:

C++代码可以改写为:

for (const auto &face : modelFaces)
{
    Face newFace(face); // Value, no need for Java-like syntax
    for (int k = 0; k < 3; ++k)
    {
        RVPoint3D pt = newFace.getPts()[k];
        ++pointMap[pt]; // auto sets to 1 on new entry
    }
    faces.push_back(newFace);
}

这是有效的,因为如果std::map中不存在某个密钥,则在使用0访问密钥时会自动创建(具有相应的值pointMap[pt])。因此,您只需递增,新值将从1开始,就像在Java代码中一样。

答案 1 :(得分:0)

使用自定义散列函数切换到无序映射,并重载==运算符可以解决这个问题

auto hashCode = [](const RVPoint3D pt)
{
    return pt.x + pt.y + pt.z;
};

std::unordered_map<RVPoint3D, int, std::function<double(RVPoint3D)>> pointMap{modelFull.getFaces().size(), hashCode};

我想我最初的尝试在某种程度上是不正确的,但这完全有效,所以也许它将来会帮助别人。