如何使用递归迭代嵌套映射中的映射?

huangapple go评论69阅读模式
英文:

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-&gt;setupUi(this);
    std::map&lt;std::string, VariableContainer&gt; myMap;

    for (int i = 0; i &lt; 3; ++i) {
        VariableContainer var;
        var.variables[&quot;A&quot; + std::to_string(i)];

        if (i == 1) {
            VariableContainer childVar;
            for (int j = 1; j &lt; 3; ++j) {
               childVar.variables[&quot;X_&quot; + std::to_string(j)];
            }
            var.variables.emplace(&quot;B&quot; + std::to_string(i), childVar);
        }
        var.variables[&quot;C&quot; + std::to_string(i)];
        myMap.emplace(&quot;Node_&quot; + std::to_string(i), var);
    }

    for (auto&amp; var : myMap) {
        std::cout &lt;&lt; &quot;var: &quot;&lt;&lt; var.first &lt;&lt; std::endl;
        if (var.second.variables.size()&gt;0) {
            for (auto&amp; child : var.second.variables) {
                std::cout &lt;&lt; &quot; child: &quot;&lt;&lt; child.first &lt;&lt; std::endl;
                if (child.second.variables.size()&gt;0) {
                    for (auto&amp; subChild : child.second.variables) {
                        std::cout &lt;&lt; &quot;  subChild: &quot;&lt;&lt; subChild.first &lt;&lt; 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 + &quot;.&quot; + child + &quot;.&quot; + subChild + &quot;.&quot; + 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 &lt;map&gt;
#include &lt;string&gt;

class VariableContainer
{
public:
    VariableContainer() {}
    std::map&lt;std::string, VariableContainer&gt; 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&lt;std::string, VariableContainer&gt; &amp;map) {
    for (auto&amp; var : map) {
        std::cout &lt;&lt; &quot;var: &quot;&lt;&lt; var.first &lt;&lt; std::endl;
        if (var.second.variables.size() &gt; 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&lt;std::string, VariableContainer&gt; variables;
};

void showMap(
	const std::string &amp;BranchName,  //I think this is necessary
	const std::map&lt;std::string, VariableContainer&gt; &amp;map
)
{
	for( const auto &amp;var : map )
	{
		std::string VarName = BranchName + var.first;
		if( var.second.variables.empty() )  //if leaf
		{	std::cout &lt;&lt; VarName &lt;&lt; std::endl;	}
		else
		{	showMap( VarName+&quot;.&quot;, var.second.variables );	}
	}
}

inline void showMap( const std::map&lt;std::string, VariableContainer&gt; &amp;map )
{	showMap( &quot;&quot;, map );	}

int main(int argc, char *argv[])
{
	std::map&lt;std::string, VariableContainer&gt; Root;
	{//construct the test data
		{
			auto &amp;Node_0 = Root[&quot;Node_0&quot;].variables;
			Node_0[&quot;A0&quot;];
			Node_0[&quot;C0&quot;];
		}
		{
			auto &amp;Node_1 = Root[&quot;Node_1&quot;].variables;
			Node_1[&quot;A1&quot;];
			auto &amp;B1 = Node_1[&quot;B1&quot;].variables;
			B1[&quot;X_1&quot;];
			B1[&quot;X_2&quot;];
		}
		{
			auto &amp;Node_2 = Root[&quot;Node_2&quot;].variables;
			Node_2[&quot;A2&quot;];
			Node_2[&quot;C2&quot;];
		}
	}

	showMap( Root );
	return 0;
}

huangapple
  • 本文由 发表于 2023年3月1日 08:50:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/75598673.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定