You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Boost库:XML项向量读写及邻接表动态属性读写学生信息

嘿,这就帮你搞定这两个Boost图库的问题,直接上代码和清晰的解释,这样你能快速上手:

1. 使用boost::write_graphml读写XML中的项向量

GraphML本身支持存储复杂类型,但Boost默认的属性映射不会直接处理向量,所以我们需要给向量类型自定义序列化/反序列化逻辑,再通过dynamic_properties注册进去。下面是完整的实现示例:

第一步:定义图和属性结构

#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/graphml.hpp>
#include <vector>
#include <fstream>
#include <sstream>

// 顶点属性:包含一个向量字段
struct VertexProps {
    std::vector<int> items;
};

// 定义图类型
using Graph = boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS, VertexProps>;

第二步:实现向量的读写转换函数

我们需要把向量转换成字符串才能存入GraphML,读取时再把字符串还原成向量:

// 把向量转成空格分隔的字符串(用于写入)
std::string vector_to_str(const std::vector<int>& vec) {
    std::ostringstream oss;
    for (size_t i = 0; i < vec.size(); ++i) {
        if (i != 0) oss << " ";
        oss << vec[i];
    }
    return oss.str();
}

// 把字符串转成向量(用于读取)
void str_to_vector(std::vector<int>& vec, const std::string& str) {
    vec.clear();
    std::istringstream iss(str);
    int val;
    while (iss >> val) {
        vec.push_back(val);
    }
}

第三步:读写GraphML文件

通过make_transform_value_property_map把转换函数和属性映射绑定,再注册到dynamic_properties中:

int main() {
    // 构建测试图,给顶点设置向量属性
    Graph g;
    auto v1 = boost::add_vertex(VertexProps{{1,2,3}}, g);
    auto v2 = boost::add_vertex(VertexProps{{4,5,6}}, g);
    boost::add_edge(v1, v2, g);

    // 写入GraphML
    std::ofstream out_file("vector_graph.graphml");
    boost::dynamic_properties dp_write;
    dp_write.property("vertex_items", boost::make_transform_value_property_map(
        vector_to_str, get(&VertexProps::items, g), str_to_vector));
    boost::write_graphml(out_file, g, dp_write, true); // true表示写入顶点ID
    out_file.close();

    // 读取GraphML
    Graph g_read;
    std::ifstream in_file("vector_graph.graphml");
    boost::dynamic_properties dp_read;
    dp_read.property("vertex_items", boost::make_transform_value_property_map(
        vector_to_str, get(&VertexProps::items, g_read), str_to_vector));
    boost::read_graphml(in_file, g_read, dp_read);
    in_file.close();

    // 验证读取结果
    auto& items = g_read[*boost::vertices(g_read).first].items;
    for (int num : items) {
        std::cout << num << " "; // 输出:1 2 3
    }
    std::cout << std::endl;

    return 0;
}

2. 使用dynamic property读写带name字段的GraphData结构体

这里分两种常见场景:GraphData是图的全局属性,或者是每个顶点的属性,两种情况的实现略有不同,我都给你列出来:

场景1:GraphData是图的全局属性

如果GraphData是整个图的元信息(比如图的名称),代码如下:

#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/graphml.hpp>
#include <fstream>
#include <string>

// 图的全局属性结构体
struct GraphData {
    std::string name;
    // 可以添加其他字段,比如创建时间、版本号等
};

// 定义图类型:把GraphData作为全局属性(最后一个模板参数)
using Graph = boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS,
                                    boost::no_property, boost::no_property, GraphData>;

int main() {
    // 创建图并设置全局属性
    Graph g;
    g[boost::graph_bundle].name = "Student_Info_Graph"; // 访问全局属性

    // 添加测试顶点和边
    auto v1 = boost::add_vertex(g);
    auto v2 = boost::add_vertex(g);
    boost::add_edge(v1, v2, g);

    // 写入GraphML
    std::ofstream out_file("global_property.graphml");
    boost::dynamic_properties dp_write;
    dp_write.property("graph_name", get(&GraphData::name, g)); // 绑定全局属性的name字段
    boost::write_graphml(out_file, g, dp_write, true);
    out_file.close();

    // 读取GraphML
    Graph g_read;
    std::ifstream in_file("global_property.graphml");
    boost::dynamic_properties dp_read;
    dp_read.property("graph_name", get(&GraphData::name, g_read));
    boost::read_graphml(in_file, g_read, dp_read);
    in_file.close();

    // 验证结果
    std::cout << "读取到的图名称:" << g_read[boost::graph_bundle].name << std::endl;
    // 输出:读取到的图名称:Student_Info_Graph

    return 0;
}

场景2:GraphData是顶点属性(每个顶点对应一个学生)

如果每个顶点代表一个学生,GraphData是学生的信息(比如姓名、年龄),代码调整如下:

#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/graphml.hpp>
#include <fstream>
#include <string>

// 顶点属性:学生信息结构体
struct GraphData {
    std::string name;
    int age;
};

// 定义图类型:把GraphData作为顶点属性(第四个模板参数)
using Graph = boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS, GraphData>;

int main() {
    // 创建图,添加学生顶点
    Graph g;
    auto alice = boost::add_vertex(GraphData{"Alice", 20}, g);
    auto bob = boost::add_vertex(GraphData{"Bob", 21}, g);
    boost::add_edge(alice, bob, g);

    // 写入GraphML
    std::ofstream out_file("student_vertices.graphml");
    boost::dynamic_properties dp_write;
    // 注册顶点的name和age属性
    dp_write.property("student_name", get(&GraphData::name, g));
    dp_write.property("student_age", get(&GraphData::age, g));
    boost::write_graphml(out_file, g, dp_write, true);
    out_file.close();

    // 读取GraphML
    Graph g_read;
    std::ifstream in_file("student_vertices.graphml");
    boost::dynamic_properties dp_read;
    dp_read.property("student_name", get(&GraphData::name, g_read));
    dp_read.property("student_age", get(&GraphData::age, g_read));
    boost::read_graphml(in_file, g_read, dp_read);
    in_file.close();

    // 验证第一个学生的信息
    auto& first_student = g_read[*boost::vertices(g_read).first];
    std::cout << "第一个学生:" << first_student.name << ",年龄:" << first_student.age << std::endl;
    // 输出:第一个学生:Alice,年龄:20

    return 0;
}

解释一下:对于std::string、int这类基础类型,Boost已经内置了读写逻辑,所以直接用get(&GraphData::name, g)获取属性映射,再注册到dynamic_properties里就可以了,不需要额外写转换函数。


内容的提问来源于stack exchange,提问作者Milan Dabhi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 08:14:57