通过树状系统进行高效迭代

时间:2013-06-19 20:34:37

标签: c++ mfc

我有一个类似树的系统,它由一个对象创建,该对象包含对另一类对象的引用列表,其中包含对另一个对象的引用列表......等等。

因此,给我一个对象树,所有不同的类型。

现在,我现在正在做的只是使用'for each'循环来获取其父级下的每个元素,直到我找到我想要的对象。 (这些对象包含我需要访问的字符串。如果此字符串与我正在查找的字符串匹配,那么我设置一个标志。可能有多个匹配,但我只需要确认一个。)

这提出了另一点,即一旦我设置了那个标志会发生什么,因为我不需要再继续下去了。这是因为如果在一个字符串上找到匹配,那么我可以假设我可以继续我的其余程序。因此,这使得树上的其余迭代毫无意义。

我在C ++ MFC中工作,因此如果重要的话我正在搜索CString。

包含“children”对象的容器层以父对象的Vector开头,后跟子对象List,后跟子对象List。

使树的分支看起来像:

Initial Vector: { 1object1, 1object2, 1object3, ..., 1objectN }

object1 List: { 2object1, 2object2, 2object3, ...,2objectN }

2object1 List: { 3object1, ... 3objectN }

if (3object1.name() == "match")
{
    flag = TRUE;
    break?
}

object1 List: { 2object1, 2object2, 2object3, ...,2objectN } 2object1 List: { 3object1, ... 3objectN } if (3object1.name() == "match") { flag = TRUE; break? }

为了保持问题的通用性,即使我使用向量和列表,我也不会对所使用的实现过于挑剔。

我的实际代码如下所示:

bool flag = FALSE;
    for each (1Object 1object in m_1Objects)
        for each (2Object 2object in 1object.Get2Objects())
            for each (3Object 3object in 2object.Get3Objects())
                if (3object.GetName() == "match") flag = TRUE;

正如您所知,一旦系统变得太大,这可能需要永远运行。特别是因为一旦标志设定,我不确定如何突破它。

这样做会更有效,更清洁吗?

2 个答案:

答案 0 :(得分:1)

嗯,有几种方法可以处理它。

最简单的 - ''最讨厌的''方法是在找到项目后抛出异常并将其捕获到循环外部。不整洁,不好,但它会起作用。你仍然可以使用std::for_each。为了说明(不是我赞成这个解决方案):

bool flag = FALSE;                                                                                                                                                  
try {
    for each (1Object 1object in m_1Objects)
        for each (2Object 2object in 1object.Get2Objects())
            for each (3Object 3object in 2object.Get3Objects())
                if (3object.GetName() == "match") throw true;
} catch (bool e) {
    flag = TRUE;
}

另一种方法是使用std::find_if而不是std::for_each,并在每个级别检查find_if返回的迭代器是否是最后一次。 (最后会表示找不到项目。)

但我认为最简单的方法是将foreach迭代实现为简单的for循环,条件语句包括标志,例如这段代码

bool flag = 0;
for (int i = 0; i < 10 && !flag; ++i) {
    std::cout << i << std::endl;
    if (5 == i)
        flag = true;
}

将输出

0
1
2
3
4
5

这对你的问题有帮助吗?

答案 1 :(得分:0)

我会将这个嵌套的搜索循环分成一个返回true / false的const方法。然后,当您找到该项目时,只需“返回true;”