C++ 给定一个向量,擦除低于itemsum的元素
这是我的函数,用于删除字符串“results”向量中的所有元素,这些字符串的长度没有“itemsnum”长。但是我有点担心它会多次调用自己,有没有更简单的方法C++ 给定一个向量,擦除低于itemsum的元素,c++,vector,C++,Vector,这是我的函数,用于删除字符串“results”向量中的所有元素,这些字符串的长度没有“itemsnum”长。但是我有点担心它会多次调用自己,有没有更简单的方法 vector<string> eraselower(vector<string> results, int itemsnum){ //erases all elements in vector which are not long enough for (unsigned j=0; j<results
vector<string> eraselower(vector<string> results, int itemsnum){ //erases all elements in vector which are not long enough
for (unsigned j=0; j<results.size(); j++){
if(results[j].length()<itemsnum ){ results.erase(results.begin()+j); }}
for (unsigned j=0; j<results.size(); j++){
if(results[j].length()<itemsnum ){ results=eraselower(results,itemsnum);}}
return results;
}
vector eraselower(vector results,int itemsnum){//删除vector中长度不够的所有元素
对于(unsigned j=0;j而言,最好的方法是使用擦除-删除习惯用法:
#include <algorithm>
#include <string>
#include <vector>
std::vector<std::string> eraselower(std::vector<std::string> results, int itemsnum)
{
results.erase(
std::remove_if(results.begin(), results.end(),
[itemsnum](const std::string & s) {
return s.size() < itemsnum; }),
results.end());
return results;
}
#包括
#包括
#包括
std::vector(std::vector结果,int itemsnum)
{
结果。删除(
std::如果(results.begin(),results.end(),则删除,
[itemsnum](常量标准::字符串和字符串){
返回s.size()
最好的方法是“擦除-删除”习惯用法:
#include <algorithm>
#include <string>
#include <vector>
std::vector<std::string> eraselower(std::vector<std::string> results, int itemsnum)
{
results.erase(
std::remove_if(results.begin(), results.end(),
[itemsnum](const std::string & s) {
return s.size() < itemsnum; }),
results.end());
return results;
}
#包括
#包括
#包括
std::vector(std::vector结果,int itemsnum)
{
结果。删除(
std::如果(results.begin(),results.end(),则删除,
[itemsnum](常量标准::字符串和字符串){
返回s.size()
您的主要问题是循环的第一个元素。例如,如果结果[2]
和结果[3]
都是短字符串,则到达j==2
并删除第二个元素,这会将之后的所有内容向下移动一个插槽,因此结果[3]
的短字符串现在位于结果[2]中
。然后,for
循环的立即将j
增加到3,因此您永远不会检查第二个短字符串,即现在的结果[2]
第二个递归循环确实负责正确地“修复”,但你是对的,这很愚蠢
非常适合这一点。请注意,它实际上不会从向量本身删除任何内容,它只是将元素向下滑动并在末尾留下垃圾,因此我们在后面调用vector::erase
,以将向量缩小到正确的大小:
vector<string> eraselower(vector<string> results, int itemsnum){
//erases all elements in vector which are not long enough
results.erase( std::remove_if( results.begin(), results.end(),
[itemsnum](const std::string& s) { return s.length() < itemsnum; } ),
results.end() );
return results;
}
vector橡皮擦下限(vector results,int itemsnum){
//删除向量中长度不够的所有元素
results.erase(std::remove_if(results.begin(),results.end(),
[itemsnum](const std::string&s){return s.length()
您可能想考虑用非const引用来获取向量,而不是通过复制,然后返回另一个修改的向量。
您的主要问题是针对<<代码>循环的第一个<代码>。如果例如“代码>结果[ 2 ] < /代码>和<代码>结果[ 3 ]
都是短字符串,您到达j==2
并删除第二个元素-这会将之后的所有内容向下移动一个插槽,因此原来是results[3]
的短字符串现在位于results[2]
。然后,for
循环的立即将j
增加到3,因此您永远不会检查第二个短字符串,即现在的结果[2]
第二个递归循环确实负责正确地“修复”,但你是对的,这很愚蠢
非常适合这一点。请注意,它实际上不会从向量本身删除任何内容,它只是将元素向下滑动并在末尾留下垃圾,因此我们在后面调用vector::erase
,以将向量缩小到正确的大小:
vector<string> eraselower(vector<string> results, int itemsnum){
//erases all elements in vector which are not long enough
results.erase( std::remove_if( results.begin(), results.end(),
[itemsnum](const std::string& s) { return s.length() < itemsnum; } ),
results.end() );
return results;
}
vector橡皮擦下限(vector results,int itemsnum){
//删除向量中长度不够的所有元素
results.erase(std::remove_if(results.begin(),results.end(),
[itemsnum](const std::string&s){return s.length()
你可能想考虑用非const引用来获取向量,而不是通过复制,然后返回另一个修改的向量。
擦除删除成语,虽然我个人更喜欢那些即使是C++初学者也容易读的解决方案。
vector<string> eraselower(const vector<string> & strings, int itemsnum)
{
vector<string> res;
res.reserve(strings.size());
for (const string & s: strings) {
if (s.length() >= itemsnum) {
res.push_back(s);
}
}
return res;
}
向量擦除器(常量向量和字符串,int itemsnum)
{
向量res;
res.reserve(strings.size());
for(常量字符串&s:strings){
如果(s.length()>=itemsnum){
res.推回(s);
}
}
返回res;
}
> p>擦除删除成语,虽然我个人更喜欢那些即使是C++初学者也容易阅读的解决方案。我会做如下:
vector<string> eraselower(const vector<string> & strings, int itemsnum)
{
vector<string> res;
res.reserve(strings.size());
for (const string & s: strings) {
if (s.length() >= itemsnum) {
res.push_back(s);
}
}
return res;
}
向量擦除器(常量向量和字符串,int itemsnum)
{
向量res;
res.reserve(strings.size());
for(常量字符串&s:strings){
如果(s.length()>=itemsnum){
res.推回(s);
}
}
返回res;
}
您在lambda正文中忘记了一个s.length()
。@aschepler:谢谢,修复了!这应该是std::remove\u如果
,您传递的是一个谓词而不是一个值。@Blastfurny:是的,的确,谢谢。今天不是个好日子。@Boris:我想问题是您的实际实现中的错误是否更容易发现:-)您在lambda正文中忘记了一个s.length()
。@aschepler:谢谢,修复了!这应该是std::remove\u如果,您传递的是一个谓词而不是一个值。@Blastfurny:是的,的确,谢谢。今天不是个好日子。@Boris:我想问题是您实际实现中的错误是否更容易发现:-)“易读”是非常主观的。其他解决方案基本上说明了正在执行的操作remove\u if
,erase
,等等,for
循环并不传达这些信息。虽然我可以理解为什么for循环应该更容易被初学者阅读,但我认为如果您理解这两个概念(您和remove_if
语法)第二个更具可读性和simple@Fureeish我同意,这是非常主观的。初学者会发现我的解决方案更具可读性。专家可能会发现擦除-删除习惯用法更具可读性。我个人可以很好地阅读这两个习惯用法(现在我查阅了擦除-删除习惯用法)。我的观点是我更喜欢