如何用递归遍历嵌套map并输出点连接的层级路径?
嵌套Map层级路径遍历解决方案
你需要遍历嵌套结构的std::map,输出所有叶子节点的完整层级路径(如Node_0.A0)。以下是你的示例代码(基于Qt MainWindow):
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); std::map<std::string, VariableContainer> myMap; for (int i = 0; i < 3; ++i) { VariableContainer var; var.variables["A" + std::to_string(i)]; if (i == 1) { VariableContainer childVar; for (int j = 1; j < 3; ++j) { childVar.variables["X_" + std::to_string(j)]; } var.variables.emplace("B" + std::to_string(i), childVar); } var.variables["C" + std::to_string(i)]; myMap.emplace("Node_" + std::to_string(i), var); } // 原遍历代码,输出层级缩进的节点名 for (auto& var : myMap) { std::cout << "var: "<< var.first << std::endl; if (var.second.variables.size()>0) { for (auto& child : var.second.variables) { std::cout << " child: "<< child.first << std::endl; if (child.second.variables.size()>0) { for (auto& subChild : child.second.variables) { std::cout << " subChild: "<< subChild.first << std::endl; } } } } } }
当前输出为:
var: Node_0 child: A0 child: C0 var: Node_1 child: A1 child: B1 subChild: X_1 subChild: X_2 child: C1 var: Node_2 child: A2 child: C2
期望输出格式为完整层级路径:
Node_0.A0 Node_0.C0 Node_1.A1 Node_1.B1.X_1 Node_1.B1.X_2 Node_1.C1 Node_2.A2 Node_2.C2
VariableContainer类定义:
#ifndef VARIABLECONTAINER_H #define VARIABLECONTAINER_H #include <map> #include <string> class VariableContainer { public: VariableContainer() {} std::map<std::string, VariableContainer> variables; }; #endif // VARIABLECONTAINER_H
你尝试的递归函数无法得到预期结果,因为它没有维护当前的路径前缀:
void MainWindow::showMap(std::map<std::string, VariableContainer> &map) { for (auto& var : map) { std::cout << "var: "<< var.first << std::endl; if (var.second.variables.size() > 0) { showMap(var.second.variables); } } }
解决方案
核心思路是在递归函数中传递当前已构建的路径前缀,每次递归时将当前节点名称拼接到前缀后,当遇到没有子节点的叶子节点时,输出完整路径。
修改后的递归函数
// 在MainWindow类中声明该函数 void MainWindow::showMap(const std::map<std::string, VariableContainer>& map, const std::string& prefix = "") { for (const auto& nodePair : map) { // 构建当前节点的完整路径 std::string currentPath = prefix.empty() ? nodePair.first : prefix + "." + nodePair.first; // 如果当前节点是叶子(没有子节点),直接输出路径 if (nodePair.second.variables.empty()) { std::cout << currentPath << std::endl; } else { // 非叶子节点,继续递归遍历子节点,传递当前路径作为前缀 showMap(nodePair.second.variables, currentPath); } } }
调用方式
在MainWindow构造函数中替换原有的遍历代码,直接调用:
showMap(myMap);
代码说明
- 路径前缀传递:通过默认参数
prefix = ""处理根节点的初始情况,根节点的路径就是自身名称。 - 叶子节点判断:当
nodePair.second.variables.empty()时,说明当前节点是叶子,输出完整路径;否则递归处理子节点,将当前路径作为新的前缀传递。 - const引用优化:使用
const std::map<std::string, VariableContainer>&避免不必要的拷贝,提升性能。
输出验证
运行修改后的代码,将得到你期望的完整层级路径输出:
Node_0.A0 Node_0.C0 Node_1.A1 Node_1.B1.X_1 Node_1.B1.X_2 Node_1.C1 Node_2.A2 Node_2.C2
内容的提问来源于stack exchange,提问作者BadRobot
相关产品推荐
相关产品推荐

