我的std::vector
std::strings
包含与此类似的数据:
[0] = ""
[1] = "Abc"
[2] = "Def"
[3] = ""
[4] = "Ghi"
[5] = ""
[6] = ""
如何获得包含1到4个4个字符串的向量? (即我想从向量的开头和结尾修剪所有空白字符串):
[0] = "Abc"
[1] = "Def"
[2] = ""
[3] = "Ghi"
目前,我正在使用一个前向迭代器来向"Abc"
和一个反向迭代器返回"Ghi"
,然后使用这些迭代器构造一个新的向量。这种方法有效,但我想知道是否有更简单的方法来修剪这些元素。
P.S。我是C ++ noob。
另外,我应该提到矢量可能完全由空字符串组成,在这种情况下,0大小的矢量将是所需的结果。
答案 0 :(得分:2)
如何使用谓词:
class StringNotEmpty
{
bool operator()(const std::string& s) { return !s.empty(); }
};
现在修剪:
vec.erase(std::find_if(vec.rbegin(), vec.rend(), StringNotEmpty()).base(), vec.end());
vec.erase(vec.begin(), std::find_if(vec.begin(), vec.end(), StringNotEmpty()));
.base()
电话可能有一个一个接一个,但一般的想法应该有效。
答案 1 :(得分:0)
你的方法是合理的。另一种方法是找到第一个字符串,然后将所有连续的字符串复制到向量中的开始(和后续)元素,之后修剪向量的结尾。
除非这是一段关键的代码,这会降低您的应用程序速度,否则它的工作重要性比您实现最有效的实现更重要。
答案 2 :(得分:0)
你所做的一切都很好。但是,如果您希望“就地”缩短单个容器而不是制作子范围的副本,则erase
可以vector
其他范围。
// Probably similar to what you already have: Find iterators for the range to keep.
std::vector<std::string>::iterator start=strs.begin(), stop=strs.end();
start = strs.begin();
while (start != stop && start->empty()) ++start;
if (start == stop) {
// all strings were empty!
strs.clear();
} else {
while (start != --stop && stop->empty()) ;
++stop;
// std::vector<std::string>(start, stop) is the desired subrange
strs.erase(stop, strs.end());
strs.erase(strs.begin(), start);
}
但我同意@Nathan:如果你已经拥有的东西对你比对此更有意义,那么请保留它,除非你知道或强烈怀疑会涉及到很多字符串。
答案 3 :(得分:0)
typedef std::vector<std::strings> Strings;
Strings myStrings;
//... currently myStrings contains "","Abc","Def","","Ghi","",""
Strings::iterator itNewBegin = myStrings.begin();
Strings::iterator itNewEnd = myStrings.end();
std::advance(itNewBegin,1);
std::advance(itNewEnd,4);
String myTrimmedStrings(itNewBegin,itNewEnd);
//... currently myTrimmedStringscontains "Abc","Def","","Ghi"
出于好奇,我希望看到你的代码使用反向迭代器。 我没有掌握从两个具有不同方向的迭代器构造新向量的方法。
答案 4 :(得分:0)
迭代器肯定是要走的路。它们使代码更具可读性和直观性。
#include <algorithm>
typedef std::vector<std::string> strVec_t;
bool notEmpty(std::string s){
return !s.empty();
}
void trim(strVec_t& vec){
//get the first and last non-empty elements
strVec_t::const_iterator first = std::find_if(vec.begin(), vec.end(), notEmpty);
strVec_t::const_reverse_iterator last = std::find_if(vec.rbegin(), vec.rend(), notEmpty);
//if every element is an empty string, delete them all
if (first == vec.end()){
vec.clear();
//make a new vector from the first to the last non-empty elements
} else {
vec = strVec_t(first, last.base());
}
}