具有不同条件的多个for循环

时间:2018-03-29 22:09:23

标签: c++ loops coding-style

我试图在数组/列表中找到一些具有一些严格条件的元素。如果没有任何元素满足严格的条件,我会尝试在宽松的条件下再次找到元素。

for( ele : list) {
    if(con1 && cond2 && cond3) {
        return ele;
    }
}    
for( ele : list) {
    if(con1 && cond2) {
        return ele;
    }
}
.....

我应该每次添加一个放松条件的for循环吗?还有更好的方法吗?

更好意味着更少的编码和良好的代码可读性。

2 个答案:

答案 0 :(得分:0)

您的描述非常模糊,但我怀疑您正在寻找类似(不完整的伪代码)的内容。

  //  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();

如果找到符合严格条件的元素,则上面立即返回,否则继续前进并跟踪与放松条件匹配的第一个元素。如果循环完成,则没有与严格条件匹配的元素,并且识别匹配宽松条件(如果有)的第一个结果。

如果有whatever_type(即一个元素)的值可以指示没有数据(例如,它是一个指针而NULL表示它指向什么都没有),逻辑可以简化从上面(例如,不需要bool值来跟踪是否找到了放宽标准的结果)。

至于这是否更好",这是完全主观的。这种方法相对于两个循环的主要优点是,如果没有元素满足严格要求,则不会重复测试。缺点是额外的簿记,以跟踪放松测试的第一场比赛,直到所有元素都按照严格的标准进行检查。

答案 1 :(得分:0)

基本答案

我想这一切都在很大程度上取决于它们有多少条件以及它们有多复杂。如果它只有三个独立的条件然后是,我会写一些类似于你的代码。它简单易读,易于维护。

在更复杂的情况下

如果还有更多条件(例如10个左右),或者您预计会有更多需要添加的条件,您可以考虑将lambda与vector一起使用:

// 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

Haven没有对此进行过测试,所以有些语法可能有点生疏,但它的一般概念应该有效。在向量中std::function包装器中使用lambdas允许大量条件只需编码一次,std::all_of允许我们迭代许多条件并验证它们中的每一个都满足某个元素。

这需要<functional><algorithm>标题。

如果您不熟悉std::functionstd::any_of,那么这些都是有用的网站:

http://en.cppreference.com/w/cpp/utility/functional/function

http://en.cppreference.com/w/cpp/algorithm/all_any_none_of