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

C++运行时构建多组向量/映射插入BST及气象数据处理问询

针对你这个在现有气象数据处理程序基础上添加BST构建功能的需求,我整理了一套可落地的技术方案,咱们一步步来看怎么实现:

核心思路与整体架构

首先明确核心目标:基于原有单文件气象数据(5万行10分钟均值),先按四种需求完成数据分组/统计,再将不同维度的向量/映射数据插入二叉搜索树(BST),同时保留原有气象属性计算功能。整体流程是:数据解析 → 按需求构建统计数据集 → 插入BST → 基于BST实现查询/导出。

1. 定义核心数据结构

先把气象数据和BST节点的基础结构定义清楚,确保后续逻辑有统一的操作对象:

气象数据结构体

对应每行10分钟的原始数据,包含时间维度和气象属性:

struct WeatherData {
    int year;
    int month;
    int day;
    int period; // 一天内的10分钟时段(共144个:24*6)
    double temperature;
    double humidity;
    double windSpeed;
    // 可扩展其他气象属性,如气压、降水量等
};

通用模板BST节点与类

为了适配不同维度的键(年月、年份)和值(均值、月份统计映射),用模板实现BST,保证通用性:

template <typename Key, typename Value>
struct BSTNode {
    Key key;
    Value value;
    BSTNode* left;
    BSTNode* right;

    BSTNode(const Key& k, const Value& v) : key(k), value(v), left(nullptr), right(nullptr) {}
};

template <typename Key, typename Value>
class BST {
private:
    BSTNode<Key, Value>* root;

    // 递归插入辅助函数
    BSTNode<Key, Value>* insertHelper(BSTNode<Key, Value>* node, const Key& key, const Value& value) {
        if (node == nullptr) return new BSTNode<Key, Value>(key, value);
        
        if (key < node->key) node->left = insertHelper(node->left, key, value);
        else if (key > node->key) node->right = insertHelper(node->right, key, value);
        // 键重复时可选择更新值或忽略,这里默认保留原有值
        return node;
    }

    // 递归查找辅助函数
    BSTNode<Key, Value>* searchHelper(BSTNode<Key, Value>* node, const Key& key) {
        if (node == nullptr || node->key == key) return node;
        return key < node->key ? searchHelper(node->left, key) : searchHelper(node->right, key);
    }

    // 中序遍历辅助函数(有序输出数据)
    void inorderHelper(BSTNode<Key, Value>* node, std::function<void(const Key&, const Value&)> visitor) {
        if (node == nullptr) return;
        inorderHelper(node->left, visitor);
        visitor(node->key, node->value);
        inorderHelper(node->right, visitor);
    }

    // 销毁节点避免内存泄漏
    void destroyNode(BSTNode<Key, Value>* node) {
        if (node == nullptr) return;
        destroyNode(node->left);
        destroyNode(node->right);
        delete node;
    }

public:
    BST() : root(nullptr) {}
    ~BST() { destroyNode(root); }

    void insert(const Key& key, const Value& value) {
        root = insertHelper(root, key, value);
    }

    BSTNode<Key, Value>* search(const Key& key) {
        return searchHelper(root, key);
    }

    void inorderTraversal(std::function<void(const Key&, const Value&)> visitor) {
        inorderHelper(root, visitor);
    }
};
2. 数据预处理与BST构建

针对四种需求,分别构建对应的数据集并插入BST:

需求a:指定年月的气象属性平均值

构建以(年,月)为键、属性均值为值的BST:

// 解析原始文件为WeatherData向量
std::vector<WeatherData> parseWeatherFile(const std::string& filename) {
    std::vector<WeatherData> data;
    std::ifstream file(filename);
    std::string line;
    while (std::getline(file, line)) {
        std::istringstream iss(line);
        WeatherData wd;
        // 假设每行格式:年 月 日 时段 温度 湿度 风速
        iss >> wd.year >> wd.month >> wd.day >> wd.period >> wd.temperature >> wd.humidity >> wd.windSpeed;
        data.push_back(wd);
    }
    return data;
}

// 构建年月均值BST(以温度为例,其他属性可复用逻辑)
BST<std::pair<int, int>, double> buildMonthlyMeanBST(const std::vector<WeatherData>& data) {
    BST<std::pair<int, int>, double> bst;
    std::map<std::pair<int, int>, std::vector<double>> monthlyTempMap;

    // 按年月分组原始数据
    for (const auto& wd : data) {
        std::pair<int, int> key = {wd.year, wd.month};
        monthlyTempMap[key].push_back(wd.temperature);
    }

    // 计算均值并插入BST
    for (const auto& entry : monthlyTempMap) {
        double mean = std::accumulate(entry.second.begin(), entry.second.end(), 0.0) / entry.second.size();
        bst.insert(entry.first, mean);
    }
    return bst;
}

需求b:指定年份各月份的气象属性平均值

构建以年份为键、月份→均值映射为值的BST:

BST<int, std::map<int, double>> buildYearlyMonthlyMeanBST(const std::vector<WeatherData>& data) {
    BST<int, std::map<int, double>> bst;
    std::map<int, std::map<int, std::vector<double>>> yearlyTempMap;

    // 按年→月分组原始数据
    for (const auto& wd : data) {
        yearlyTempMap[wd.year][wd.month].push_back(wd.temperature);
    }

    // 计算每年各月均值并插入BST
    for (const auto& yearEntry : yearlyTempMap) {
        std::map<int, double> monthlyMeans;
        for (const auto& monthEntry : yearEntry.second) {
            double mean = std::accumulate(monthEntry.second.begin(), monthEntry.second.end(), 0.0) / monthEntry.second.size();
            monthlyMeans[monthEntry.first] = mean;
        }
        bst.insert(yearEntry.first, monthlyMeans);
    }
    return bst;
}

需求c:指定年份各月份的气象属性总值

逻辑和需求b几乎一致,只需把均值计算改为总和:

BST<int, std::map<int, double>> buildYearlyMonthlyTotalBST(const std::vector<WeatherData>& data) {
    BST<int, std::map<int, double>> bst;
    std::map<int, std::map<int, std::vector<double>>> yearlyTempMap;

    for (const auto& wd : data) {
        yearlyTempMap[wd.year][wd.month].push_back(wd.temperature);
    }

    for (const auto& yearEntry : yearlyTempMap) {
        std::map<int, double> monthlyTotals;
        for (const auto& monthEntry : yearEntry.second) {
            double total = std::accumulate(monthEntry.second.begin(), monthEntry.second.end(), 0.0);
            monthlyTotals[monthEntry.first] = total;
        }
        bst.insert(yearEntry.first, monthlyTotals);
    }
    return bst;
}
3. 整合原有气象计算功能

基于BST实现四种需求的交互逻辑:

// 需求a:查询指定年月的均值
void queryMonthlyMean(BST<std::pair<int, int>, double>& bst, int year, int month) {
    auto node = bst.search({year, month});
    if (node) {
        std::cout << "[" << year << "-" << month << "] 温度平均值:" << node->value << std::endl;
    } else {
        std::cout << "该年月无数据记录" << std::endl;
    }
}

// 需求b:查询指定年份各月均值
void queryYearlyMonthlyMean(BST<int, std::map<int, double>>& bst, int year) {
    auto node = bst.search(year);
    if (!node) {
        std::cout << "该年份无数据记录" << std::endl;
        return;
    }
    std::cout << year << "年各月温度平均值:" << std::endl;
    for (const auto& entry : node->value) {
        std::cout << "  " << entry.first << "月:" << entry.second << std::endl;
    }
}

// 需求d:导出指定年份各月均值到CSV
void exportYearlyMeanToCSV(BST<int, std::map<int, double>>& bst, int year, const std::string& filename) {
    auto node = bst.search(year);
    if (!node) {
        std::cout << "该年份无数据记录" << std::endl;
        return;
    }
    std::ofstream csvFile(filename);
    csvFile << "月份,温度平均值\n";
    for (const auto& entry : node->value) {
        csvFile << entry.first << "," << entry.second << "\n";
    }
    std::cout << "CSV文件已导出至:" << filename << std::endl;
}
4. 关键细节与优化点
  • 键的比较逻辑:用std::pair<int,int>作为年月键时,C++默认按年→月的顺序比较,正好符合时间排序需求,无需自定义比较运算符。
  • 内存管理:BST类的析构函数实现了递归销毁节点,避免内存泄漏。
  • 效率优化:5万行数据量级下,BST的O(log n)查找/插入效率完全够用;如果后续数据量大幅增长,可考虑平衡BST(如AVL树、红黑树),但当前需求无需过度设计。
  • 扩展性:模板BST支持任意键值类型,后续新增气象属性或统计维度时,只需复用现有BST结构,修改数据分组逻辑即可。

内容的提问来源于stack exchange,提问作者Aashish Pandav

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 09:06:33