具有不同条件的多个 for 循环
Multiple for loops with different conditions
我试图在 array/list 中找到一个具有一些严格条件的元素。如果 none 个元素满足严格条件,我将尝试以宽松的条件再次找到该元素。
for( ele : list) {
if(con1 && cond2 && cond3) {
return ele;
}
}
for( ele : list) {
if(con1 && cond2) {
return ele;
}
}
.....
我是否应该每次都添加一个条件宽松的 for
循环?有没有更好的方法?
更好意味着更少的编码和良好的代码可读性。
您的描述非常含糊,但我怀疑您正在寻找类似(不完整 pseudo-code)的内容。
// assuming the relaxed conditions are a subset of the strict conditions
whatever_type relaxed_return_value;
bool relaxed_found = false;
for (auto &element : some_list)
{
if (cond1 && cond2) // check relaxed conditions first
{
if (cond3) // check remaining strict conditions
{
return element; // return immediately on matching strict conditions
}
else if (!relaxed_found)
{
relaxed_return_value = element;
relaxed_found = true;
}
}
}
if (relaxed_found)
return relaxed_return_value;
else
indicate_no_value_found();
如果找到符合严格条件的元素,则立即执行上述returns,否则继续跟踪第一个符合宽松条件的元素。如果循环完成,则没有匹配严格条件的元素,并识别第一个匹配宽松条件(如果有)的结果。
如果 whatever_type
的值(即元素的值)可以指示没有数据(例如,它是一个指针,而 NULL
指示它什么都不指向),则逻辑可以简化为以上(例如,不需要 bool
值来跟踪是否已找到符合宽松标准的结果)。
至于这是否"better",那是完全主观的。这种方法相对于两个循环的主要优点是,如果没有元素满足严格要求,则不会重复测试。缺点是额外 book-keeping 跟踪宽松测试的第一场比赛,直到根据严格标准检查所有元素。
基本答案
我想这在很大程度上取决于条件的数量和复杂程度。如果只有三个单独的条件,那么是的,我会编写类似于您的代码的内容。它简单易读和易于维护。
在更复杂的情况下
如果有更多条件(比如 10 个左右)或者您预计需要添加更多条件,您可以考虑将 lambda 与向量一起使用:
// sample conditions for integers. Most strict condition is
// an even integer greater than 2 and less than 10
const std::vector<std::function<bool(int)>> conditions{
[](int elem) {return elem < 10;},
[](int elem) {return elem > 2;},
[](int elem) {return elem % 2 == 0;}
// add as many more conditions you wish...
// top condition is the one that will be relaxed first
};
// This will bit-by bit relax the conditions by ignoring more and more of them
auto start_iterator = conditions.begin();
while (start_iterator != conditions.end())
{
for (const auto& elem : list)
{
bool fulfills_all = std::all_of(start_iterator, conditions.end(), [] (std::function<bool(int)> cond) {
// for each active condition, test the condition on the element
return cond(elem);
});
if (fulfills_all)
return elem;
}
// If we get here, that means no element fulfilled all the conditions.
// Relax them by ignoring one more
start_iterator++;
}
// If we reach this point, then no element fulfilled even the most relaxed condition
还没有真正测试过这个,所以一些语法可能有点生疏,但它的总体思路应该是可行的。在向量的 std::function
包装器中使用 lambda 允许大量条件只需编码一次,并且 std::all_of
允许我们迭代许多条件并验证它们中的每一个都满足某个元素。
这需要 <functional>
和 <algorithm>
headers。
如果您不熟悉 std::function
或 std::any_of
那么这些是有用的网站:
http://en.cppreference.com/w/cpp/utility/functional/function
我试图在 array/list 中找到一个具有一些严格条件的元素。如果 none 个元素满足严格条件,我将尝试以宽松的条件再次找到该元素。
for( ele : list) {
if(con1 && cond2 && cond3) {
return ele;
}
}
for( ele : list) {
if(con1 && cond2) {
return ele;
}
}
.....
我是否应该每次都添加一个条件宽松的 for
循环?有没有更好的方法?
更好意味着更少的编码和良好的代码可读性。
您的描述非常含糊,但我怀疑您正在寻找类似(不完整 pseudo-code)的内容。
// assuming the relaxed conditions are a subset of the strict conditions
whatever_type relaxed_return_value;
bool relaxed_found = false;
for (auto &element : some_list)
{
if (cond1 && cond2) // check relaxed conditions first
{
if (cond3) // check remaining strict conditions
{
return element; // return immediately on matching strict conditions
}
else if (!relaxed_found)
{
relaxed_return_value = element;
relaxed_found = true;
}
}
}
if (relaxed_found)
return relaxed_return_value;
else
indicate_no_value_found();
如果找到符合严格条件的元素,则立即执行上述returns,否则继续跟踪第一个符合宽松条件的元素。如果循环完成,则没有匹配严格条件的元素,并识别第一个匹配宽松条件(如果有)的结果。
如果 whatever_type
的值(即元素的值)可以指示没有数据(例如,它是一个指针,而 NULL
指示它什么都不指向),则逻辑可以简化为以上(例如,不需要 bool
值来跟踪是否已找到符合宽松标准的结果)。
至于这是否"better",那是完全主观的。这种方法相对于两个循环的主要优点是,如果没有元素满足严格要求,则不会重复测试。缺点是额外 book-keeping 跟踪宽松测试的第一场比赛,直到根据严格标准检查所有元素。
基本答案
我想这在很大程度上取决于条件的数量和复杂程度。如果只有三个单独的条件,那么是的,我会编写类似于您的代码的内容。它简单易读和易于维护。
在更复杂的情况下
如果有更多条件(比如 10 个左右)或者您预计需要添加更多条件,您可以考虑将 lambda 与向量一起使用:
// sample conditions for integers. Most strict condition is
// an even integer greater than 2 and less than 10
const std::vector<std::function<bool(int)>> conditions{
[](int elem) {return elem < 10;},
[](int elem) {return elem > 2;},
[](int elem) {return elem % 2 == 0;}
// add as many more conditions you wish...
// top condition is the one that will be relaxed first
};
// This will bit-by bit relax the conditions by ignoring more and more of them
auto start_iterator = conditions.begin();
while (start_iterator != conditions.end())
{
for (const auto& elem : list)
{
bool fulfills_all = std::all_of(start_iterator, conditions.end(), [] (std::function<bool(int)> cond) {
// for each active condition, test the condition on the element
return cond(elem);
});
if (fulfills_all)
return elem;
}
// If we get here, that means no element fulfilled all the conditions.
// Relax them by ignoring one more
start_iterator++;
}
// If we reach this point, then no element fulfilled even the most relaxed condition
还没有真正测试过这个,所以一些语法可能有点生疏,但它的总体思路应该是可行的。在向量的 std::function
包装器中使用 lambda 允许大量条件只需编码一次,并且 std::all_of
允许我们迭代许多条件并验证它们中的每一个都满足某个元素。
这需要 <functional>
和 <algorithm>
headers。
如果您不熟悉 std::function
或 std::any_of
那么这些是有用的网站:
http://en.cppreference.com/w/cpp/utility/functional/function