我有一个类似树的系统,它由一个对象创建,该对象包含对另一类对象的引用列表,其中包含对另一个对象的引用列表......等等。
因此,给我一个对象树,所有不同的类型。
现在,我现在正在做的只是使用'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;
正如您所知,一旦系统变得太大,这可能需要永远运行。特别是因为一旦标志设定,我不确定如何突破它。
这样做会更有效,更清洁吗?
答案 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;”