繁体   English   中英

std :: vector中的字符串验证

[英]string validation in std::vector

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

#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;
}

这样可以很好地运行,并为我提供所需的结果。我的问题是,在标准算法或Boost库中是否还有其他方法可以代替当前方法使用,从而提高性能?

包括对验证算法应验证哪些内容的描述将是不错的选择,但我想消息来源是自我记录。 为了找出字符串向量是否仅包含包含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) { ... }是一个lambda表达式,用于描述应使用的条件std::none_of 放在一起,这将检查向量中是否存在不包含c的字符串,如果不存在则返回true如果存在则返回false

相对于此代码,运行时的主要优点是,一旦找到不包含c的字符串,它将立即停止检查; 除此之外,它通常更短(除非std::string::find包含巧妙的优化,这并非不可能)。

旁注:由于依赖参数的名称查找,可能会在该代码中遗漏许多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::end很好,因为如果它们存在,则假定它们提供更好的匹配度是理智的。

(授予std::beginstd::end使用.begin().end()成员函数的默认行为,使得这些beginend大都是不必要的,但是我在现实生活中已经看到了一些奇怪的事情码。)

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM