简体   繁体   English

std :: vector中的字符串验证

[英]string validation in std::vector

I am working on a code where I need to validate a std::vector filled with multiple std::string objects. 我正在编写需要验证由多个std::string对象填充的std::vector的代码。 The logic is that I need to check if all of the objects are valid or not. 逻辑是我需要检查所有对象是否有效。 If yes then display a message saying that input vector is valid, error otherwise. 如果是,则显示一条消息,指出输入向量有效,否则错误。 Here is what I have so far. 这是我到目前为止所拥有的。

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

This runs fine and gives me the result that I need.My question is, Is there any other better/performance efficient approach in standard algorithm or boost library that I can use instead of my current approach? 这样可以很好地运行,并为我提供所需的结果。我的问题是,在标准算法或Boost库中是否还有其他方法可以代替当前方法使用,从而提高性能?

It would have been nice to include a description of what the validation algorithm should validate, but I suppose the source is self-documenting. 包括对验证算法应验证哪些内容的描述将是不错的选择,但我想消息来源是自我记录。 To find out whether a vector of strings contains only strings that contain a c , I'd use 为了找出字符串向量是否仅包含包含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 checks if no element in a range satisfies a condition, and the [](std::string const &s) { ... } is a lambda expression that describes the condition std::none_of is supposed to use. std::none_of检查范围内是否没有元素满足条件,并且[](std::string const &s) { ... }是一个lambda表达式,用于描述应使用的条件std::none_of Put together, this checks whether there is a string that doesn't contain a c in the vector, returns true if there wasn't and false if there was. 放在一起,这将检查向量中是否存在不包含c的字符串,如果不存在则返回true如果存在则返回false

The main runtime advantage over your code of this is that it stops checking as soon as it finds a string that doesn't contain a c ; 相对于此代码,运行时的主要优点是,一旦找到不包含c的字符串,它将立即停止检查; other than that, it is mostly shorter (unless the implementation of std::string::find contains clever optimizations, which is not impossible). 除此之外,它通常更短(除非std::string::find包含巧妙的优化,这并非不可能)。

Side note: It would be possible to leave out many of the std:: in that code because of argument-dependent name lookup . 旁注:由于依赖参数的名称查找,可能会在该代码中遗漏许多std:: I left some out in the original code but put them back in after @BoBTFish commented on it to avoid confusion; 我在原始代码中省略了一些内容,但在@BoBTFish对它进行注释后再放回去,以避免造成混淆; I tend to leave them out for begin and end because I'm used to doing it. 我倾向于将它们留给beginend因为我已经习惯了。 This is because of a (somewhat) useful trick in the context of templates that has no real bearing on the above function, but here it is (if you're interested): 这是因为在模板的上下文中有一个(某种)有用的技巧,与上面的功能没有实际的联系,但是这里是(如果您有兴趣的话):

If you want this validation routine to work for more than vectors, you could write 如果您希望此验证例程可用于多个向量,则可以编写

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

This is adapted from a similar technique for std::swap described in Effective C++ by Scott Meyers; 这是由Scott Meyers在Effective C ++中描述的std::swap的类似技术改编而成; the useful thing about it is that if there are fitting implementations of begin(...) and end(...) in the namespace where the type to which Container refers is defined, they are preferred over std::begin and std::end -- which is good because if they exist, it is sane to assume that they provide a better fit. 有用的是,如果在定义Container引用的类型的名称空间中有begin(...)end(...)合适实现,则它们比std::beginstd::end更可取std::end很好,因为如果它们存在,则假定它们提供更好的匹配度是理智的。

(Granted that std::begin and std::end 's default behavior of using the .begin() and .end() member functions makes such implementations of begin and end mostly unnecessary, but I have seen stranger things in real-life code.) (授予std::beginstd::end使用.begin().end()成员函数的默认行为,使得这些beginend大都是不必要的,但是我在现实生活中已经看到了一些奇怪的事情码。)

EDIT: I didn't think of std::none_of right away; 编辑:我没想到std::none_of马上; the original solution used std::find_if . 原始解决方案使用std::find_if std::find_if also works, of course, but std::none_of is rather obviously a better fit. std::find_if当然也可以,但是std::none_of显然更合适。

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

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