0

我有一个树状系统,它由一个对象创建,该对象包含对另一种类型对象的引用列表,该对象包含对另一个对象的引用列表……等等。

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

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

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

我在 C++ MFC 中工作,因此如果这很重要,我正在寻找一个 CString。

包含“子”对象的容器层以父对象的向量开始,然后是子对象列表,然后是子对象列表。

使树的分支看起来像:

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

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;

正如你所知道的,一旦系统变得太大,这可能需要永远运行。特别是因为一旦设置了标志,我不确定如何摆脱它。

什么是更有效和更清洁的方法?

4

2 回答 2

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

这对你的问题有帮助吗?

于 2013-06-19T21:00:53.290 回答
0

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

于 2013-06-19T20:54:30.423 回答