英文:
How to iterate through a map of nested maps using recursion?
问题
我有嵌套的映射,需要遍历每个级别以打印所有的值。
这个映射是为了向您展示我正在尝试使用"递归"解决的问题的示例。
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 + "." + child + "." + subChild + "." + nsubChilds
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.h:
#ifndef VARIABLECONTAINER_H
#define VARIABLECONTAINER_H
#include <map>
#include <string>
class VariableContainer
{
public:
    VariableContainer() {}
    std::map<std::string, VariableContainer> variables;
};
#endif // VARIABLECONTAINER_H
我可以在其他映射中嵌套映射,类似于分支。我认为使用递归是一个好的解决方案,因为每次执行程序时嵌套映射的数量都不同。
例如,我可能有类似这样的内容:Node_1.B1.X_1.Y_1.Z_1
我尝试了以下递归函数,但没有获得期望的输出。
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);
        }
    }
}
有没有什么想法或建议来解决这个问题?
英文:
I have nested maps and I need to iterate through each level to print all the values.
This map is to show you an example of a problem that I am trying to solve using recursion.
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;
                    }
                }
            }
        }
    }
}
This is the output:
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
But I need to get the output in the following structure:  node + "." + child + "." + subChild + "." + nsubChilds
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
This is the VariableContainer.h
#ifndef VARIABLECONTAINER_H
#define VARIABLECONTAINER_H
#include <map>
#include <string>
class VariableContainer
{
public:
    VariableContainer() {}
    std::map<std::string, VariableContainer> variables;
};
#endif // VARIABLECONTAINER_H
I could have maps nested within other maps, something like a branch. I think that using recursion is a good solution since the number of nested maps is different on each execution of the program.
For example, I could have something like this: Node_1.B1.X_1.Y_1.Z_1
I tried the following recursive function but I'm not getting the desired output.
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);
        }
    }
}
Any Idea or suggestion to solve this?
答案1
得分: 2
将分支名称传递给函数 showMap()。
例如:
class VariableContainer
{
public:
    VariableContainer() {}
    std::map<std::string, VariableContainer> variables;
};
void showMap(
    const std::string &BranchName,  //我认为这是必要的
    const std::map<std::string, VariableContainer> &map
)
{
    for (const auto &var : map)
    {
        std::string VarName = BranchName + var.first;
        if (var.second.variables.empty())  //如果是叶子节点
        {
            std::cout << VarName << std::endl;
        }
        else
        {
            showMap(VarName + ".", var.second.variables);
        }
    }
}
inline void showMap(const std::map<std::string, VariableContainer> &map)
{
    showMap("", map);
}
int main(int argc, char *argv[])
{
    std::map<std::string, VariableContainer> Root;
    {//构建测试数据
        {
            auto &Node_0 = Root["Node_0"].variables;
            Node_0["A0"];
            Node_0["C0"];
        }
        {
            auto &Node_1 = Root["Node_1"].variables;
            Node_1["A1"];
            auto &B1 = Node_1["B1"].variables;
            B1["X_1"];
            B1["X_2"];
        }
        {
            auto &Node_2 = Root["Node_2"].variables;
            Node_2["A2"];
            Node_2["C2"];
        }
    }
    showMap(Root);
    return 0;
}
这是您提供的代码的翻译部分。
英文:
Pass the branch name to the function showMap().
e.g.
class VariableContainer
{
public:
	VariableContainer() {}
	std::map<std::string, VariableContainer> variables;
};
void showMap(
	const std::string &BranchName,  //I think this is necessary
	const std::map<std::string, VariableContainer> &map
)
{
	for( const auto &var : map )
	{
		std::string VarName = BranchName + var.first;
		if( var.second.variables.empty() )  //if leaf
		{	std::cout << VarName << std::endl;	}
		else
		{	showMap( VarName+".", var.second.variables );	}
	}
}
inline void showMap( const std::map<std::string, VariableContainer> &map )
{	showMap( "", map );	}
int main(int argc, char *argv[])
{
	std::map<std::string, VariableContainer> Root;
	{//construct the test data
		{
			auto &Node_0 = Root["Node_0"].variables;
			Node_0["A0"];
			Node_0["C0"];
		}
		{
			auto &Node_1 = Root["Node_1"].variables;
			Node_1["A1"];
			auto &B1 = Node_1["B1"].variables;
			B1["X_1"];
			B1["X_2"];
		}
		{
			auto &Node_2 = Root["Node_2"].variables;
			Node_2["A2"];
			Node_2["C2"];
		}
	}
	showMap( Root );
	return 0;
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论