C++数据结构--VertexFaceMap(适用于一对多映射关系)

53 阅读1分钟
#include <vector>
#include <algorithm>
#include <iostream>

class VertexFaceMap {
public:
    struct Entry {
        int vid;                    // 顶点 ID
        std::vector<int> faces;     // 关联的三角面片 ID
    };

    // 添加一条记录(构建阶段使用)
    void addFace(int vid, int faceId) {
        temp_data.push_back({vid, faceId});
    }

    // 构建最终映射(排序 + 合并)
    void build() {
        // 1. 按 vid 排序
        std::sort(temp_data.begin(), temp_data.end(),
                  [](const auto& a, const auto& b) { return a.vid < b.vid; });

        // 2. 合并相同 vid 的面片
        mapping.clear();
        mapping.reserve(temp_data.size());

        for (size_t i = 0; i < temp_data.size(); ) {
            int current_vid = temp_data[i].vid;
            std::vector<int> faces;
            while (i < temp_data.size() && temp_data[i].vid == current_vid) {
                faces.push_back(temp_data[i].face);
                ++i;
            }
            mapping.push_back({current_vid, std::move(faces)});
        }

        // 3. 清理临时数据
        temp_data.clear();
        temp_data.shrink_to_fit();
    }

    // 查找某个顶点对应的面片列表(返回 const 引用,避免拷贝)
    const std::vector<int>* find(int vid) const {
        auto it = std::lower_bound(mapping.begin(), mapping.end(), vid,
            [](const Entry& e, int v) { return e.vid < v; });

        if (it != mapping.end() && it->vid == vid) {
            return &it->faces;
        }
        return nullptr;
    }

    size_t size() const { return mapping.size(); }

private:
    struct Temp {
        int vid;
        int face;
    };

    std::vector<Temp> temp_data;   // 构建阶段用 (未合并)
    std::vector<Entry> mapping;    // 最终映射数据 (已排序)
};


使用示例

int main() {
    VertexFaceMap vmap;

    // 添加数据(构建阶段)
    vmap.addFace(10023, 0);
    vmap.addFace(10023, 1);
    vmap.addFace(5001, 2);
    vmap.addFace(88888, 3);
    vmap.addFace(88888, 4);

    // 构建映射(必须调用一次)
    vmap.build();

    // 查找顶点对应的面片
    if (auto faces = vmap.find(10023)) {
        std::cout << "顶点 10023 对应的面片: ";
        for (int f : *faces) std::cout << f << " ";
        std::cout << "\n";
    } else {
        std::cout << "顶点 10023 不存在\n";
    }

    // 查找不存在的顶点
    if (auto faces = vmap.find(42)) {
        std::cout << "顶点 42 对应的面片数: " << faces->size() << "\n";
    } else {
        std::cout << "顶点 42 不存在\n";
    }

    return 0;
}