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 对其发表评论以避免混淆之后;我倾向于将它们排除在 begin
和 end
之外,因为我已经习惯这样做了。这是因为模板上下文中的一个(有点)有用的技巧对上述功能没有真正的影响,但这里是(如果你感兴趣的话):
如果您希望此验证例程适用于多个向量,您可以编写
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::begin
和 std::end
-- 这很好,因为如果它们存在,假设它们提供更好的拟合是理智的。
(假设 std::begin
和 std::end
使用 .begin()
和 .end()
成员函数的默认行为使得 begin
和 end
大部分是不必要的,但我在现实生活中的代码中看到过奇怪的事情。)
编辑:我没有立即想到 std::none_of
;原始解决方案使用 std::find_if
。 std::find_if
当然也可以,但是 std::none_of
显然更合适。
我正在编写一个代码,我需要验证一个 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 对其发表评论以避免混淆之后;我倾向于将它们排除在 begin
和 end
之外,因为我已经习惯这样做了。这是因为模板上下文中的一个(有点)有用的技巧对上述功能没有真正的影响,但这里是(如果你感兴趣的话):
如果您希望此验证例程适用于多个向量,您可以编写
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::begin
和 std::end
-- 这很好,因为如果它们存在,假设它们提供更好的拟合是理智的。
(假设 std::begin
和 std::end
使用 .begin()
和 .end()
成员函数的默认行为使得 begin
和 end
大部分是不必要的,但我在现实生活中的代码中看到过奇怪的事情。)
编辑:我没有立即想到 std::none_of
;原始解决方案使用 std::find_if
。 std::find_if
当然也可以,但是 std::none_of
显然更合适。