C++之从txt文档读取不同z截面构成的点集

点集数据存在一个txt文档,每行代表一个点,依次为xyz,逗号间隔,该数据点为垂直于Z轴不同截面上的点集,按z从小到大依次排列。

现在用c++读取该文档,存到容器中,并且按z轴分组,就是把不同截面上的点做好区分,如下:

#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
#include <map>
​
struct Point {
    float x, y, z;
};
​
int main() {
    std::ifstream file("data.txt"); // 假设你的文件名为data.txt
    if (!file.is_open()) {
        std::cerr << "无法打开文件" << std::endl;
        return 1;
    }
​
    std::map<float, std::vector<Point>> pointsByZ; // 用于按z轴值分组存储点的容器
    std::string line;
    while (getline(file, line)) {
        std::istringstream iss(line);
        float x, y, z;
        char comma; // 用于读取逗号
​
        if (!(iss >> x >> comma >> y >> comma >> z)) {
            std::cerr << "读取数据失败" << std::endl;
            continue; // 跳过这一行
        }
​
        // 将读取的点添加到按z轴值分组的容器中
        pointsByZ[z].push_back({x, y, z});
    }
​
    file.close();
​
    // 遍历map,打印每个z值及其对应的点集
    for (const auto& z_points_pair : pointsByZ) {
        std::cout << "Z值: " << z_points_pair.first << std::endl;
        for (const auto& point : z_points_pair.second) {
            std::cout << "点坐标: (" << point.x << ", " << point.y << ", " << point.z << ")" << std::endl;
        }
    }
​
    return 0;
}

在这个示例中,使用了 std::map<float, std::vector<Point>> 来存储按 z 轴值分组的点。map 的键是 z 轴的值,值是一个 std::vector<Point>,它包含了所有具有相同 z 轴值的点。

在读取文件时,每读取到一个点,就根据它的 z 值将其添加到 pointsByZ 容器中对应的 vector 里。这样,所有具有相同 z 值的点都会被归类到一起。

最后,我使用了一个范围基于的 for 循环来遍历 map,并打印出每个 z 值及其对应的点集。

请注意,map 会根据键(在这个例子中是 z 轴的值)自动排序,所以输出的点集会按照 z 值的升序排列。如果你需要根据文件中点出现的顺序来保持顺序,你可能需要使用其他的数据结构,比如 std::unordered_map,或者在读取点时记录它们的顺序。

补充:

std::map 是 C++ 标准库中的一个关联容器,它存储了由键值对组成的元素。每个键值对包含一个键(key)和一个值(value)。std::map 中的元素是唯一的,这意味着每个键只能映射到一个值,而且键是有序的。

特点:

  1. 键值对存储:std::map 存储的数据是键值对,其中键是唯一的。

  2. 自动排序:std::map 根据键的顺序自动排序存储元素,通常是按照键的升序。

  3. 唯一键:每个键在 std::map 中必须是唯一的。

  4. 双向迭代器:std::map 提供了双向迭代器,可以向前和向后遍历元素。

  5. 对数时间复杂度:大多数操作(如插入、查找和删除)的时间复杂度为 O(log n)。

基本操作:

  • 插入:使用 insert 或 operator[] 插入键值对。

  • 查找:使用 find 根据键查找元素。

  • 删除:使用 erase 删除一个或多个元素。

  • 遍历:使用迭代器遍历所有元素。

示例代码:

#include <iostream>
#include <map>
​
int main() {
    // 创建一个 map,键为 int 类型,值为 string 类型
    std::map<int, std::string> myMap;
​
    // 插入元素
    myMap[1] = "Apple";
    myMap[2] = "Banana";
    myMap[3] = "Cherry";
​
    // 遍历 map 并打印键值对
    for (const auto& pair : myMap) {
        std::cout << "Key: " << pair.first << ", Value: " << pair.second << std::endl;
    }
​
    // 查找元素
    auto it = myMap.find(2);
    if (it != myMap.end()) {
        std::cout << "Found: " << it->second << std::endl;
    } else {
        std::cout << "Not found" << std::endl;
    }
​
    // 删除元素
    myMap.erase(2);
​
    // 再次遍历 map
    for (const auto& pair : myMap) {
        std::cout << "Key: " << pair.first << ", Value: " << pair.second << std::endl;
    }
​
    return 0;
}

输出:

Key: 1, Value: AppleKey: 3, Value: CherryFound: BananaKey: 1, Value: AppleKey: 3, Value: Cherry

在这个示例中,我们创建了一个 std::map,其中键是整数,值是字符串。我们插入了一些键值对,然后遍历 map 打印了所有的键值对。接着,我们查找了键为 2 的元素,并在找到后打印了它的值。然后,我们删除了键为 2 的元素,并再次遍历 map 打印剩余的键值对。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值