std::vector 中的字符串验证

string validation in std::vector

我正在编写一个代码,我需要验证一个 std::vector 填充了多个 std::string 对象。逻辑是我需要检查所有对象是否有效。如果是,则显示一条消息,说明输入向量有效,否则出错。这是我目前所拥有的。

#include<iostream>
#include<vector>
#include<numeric>
#include<boost/foreach.hpp>

short multiply(short s1,short s2)
{
    return s1*s2;
}
bool validate(const std::vector<std::string> &in)
{
    std::vector<short>check(in.size(),0);
    auto checkitr = check.begin();

    BOOST_FOREACH(std::string str,in)
    {
        for(auto itr = str.begin(); itr != str.end(); ++itr)
        {
            if(*itr == 'c')
            {
                *checkitr = 1;
                break;
            }
        }
        ++checkitr;
    }
    short product = std::accumulate(check.begin(),check.end(),1,multiply);

    return ( (product) ? true : false );
}

int main()
{
    std::string s1("abcd");
    std::string s2("lncd");
    std::vector<std::string>iVec;

    iVec.push_back(s1);
    iVec.push_back(s2);

    bool isValid = validate(iVec);

    if(isValid){
        std::cout<<"This Vector is valid   "<<std::endl;    
    }
    else
    {   
        std::cout<<"This is an invalid vector  "<<std::endl;        
    }

    iVec.push_back(std::string("ghkd"));

    isValid = validate(iVec);

    if(isValid){
        std::cout<<"This Vector is valid  "<<std::endl;

    }
    else
    {
        std::cout<<"This is an invalid vector  "<<std::endl;
    }   

    return 0;
}

这运行良好并给出了我 need.My 问题的结果, 我可以使用标准算法或 boost 库中的任何其他 better/performance 有效方法来代替我当前的方法吗?

最好包含验证算法应验证的内容的描述,但我想源代码是自我记录的。要确定字符串向量是否仅包含包含 c 的字符串,我会使用

#include <algorithm> // for std::none_of
#include <iterator>  // for std::begin, std::end

bool validate(const std::vector<std::string> &in)
{
  return std::none_of(std::begin(in),
                      std::end  (in),
                      [](std::string const &s) {
                        return s.find('c') == std::string::npos;
                      });
}

std::none_of 检查范围内是否没有元素满足条件,[](std::string const &s) { ... } 是描述条件 std::none_of 应该使用的 lambda 表达式。放在一起,这将检查向量中是否存在不包含 c 的字符串,如果不存在,则为 returns true,如果存在,则为 false

与您的代码相比,运行时的主要优势在于它会在发现不包含 c 的字符串后立即停止检查;除此之外,它大多更短(除非 std::string::find 的实现包含巧妙的优化,这并非不可能)。

旁注: 由于 argument-dependent name lookup,可能会在该代码中省略许多 std::。我在原始代码中遗漏了一些但将它们放回原处 在@BoBTFish 对其发表评论以避免混淆之后;我倾向于将它们排除在 beginend 之外,因为我已经习惯这样做了。这是因为模板上下文中的一个(有点)有用的技巧对上述功能没有真正的影响,但这里是(如果你感兴趣的话):

如果您希望此验证例程适用于多个向量,您可以编写

template<typename Container>
bool validate(Container &&in)
{
  using std::begin;
  using std::end;

  return std::none_of(begin(std::forward<Container>(in)),
                      end  (std::forward<Container>(in)),
                      [](std::string const &s) {
                        return s.find('c') == std::string::npos;
                      });
}

这改编自 Scott Meyers 在 Effective C++ 中描述的 std::swap 的类似技术;它的有用之处在于,如果在定义 Container 所指类型的名称空间中存在 begin(...)end(...) 的合适实现,则它们优于 std::beginstd::end -- 这很好,因为如果它们存在,假设它们提供更好的拟合是理智的。

(假设 std::beginstd::end 使用 .begin().end() 成员函数的默认行为使得 beginend 大部分是不必要的,但我在现实生活中的代码中看到过奇怪的事情。)

编辑:我没有立即想到 std::none_of;原始解决方案使用 std::find_ifstd::find_if 当然也可以,但是 std::none_of 显然更合适。