首页 文章

将Java LinkedHashMap转换为C std :: map

提问于
浏览
0

我正在尝试将程序从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 one为7967.两者共检查了45234个元素,因此它似乎正在通过潜在的密钥正确迭代 .

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

2 回答

  • 0

    在新 Map 项目的 java 版本中,您将 v 设置为 0 ,然后在将其放入 Map 时为其添加 1 . \ _在 C++ 版本中,你把它放在 0 中 .

    Java

    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); // ?
    

    Side Note:

    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 中不存在某个键,则在使用 pointMap[pt] 访问它时会自动创建一个键(具有相应的值 0 ) . 因此,您只需递增,新值将从 1 开始,就像在 Java 代码中一样 .

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

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

相关问题