C++ 给定一个向量,擦除低于itemsum的元素

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

这是我的函数,用于删除字符串“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.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我同意,这是非常主观的。初学者会发现我的解决方案更具可读性。专家可能会发现擦除-删除习惯用法更具可读性。我个人可以很好地阅读这两个习惯用法(现在我查阅了擦除-删除习惯用法)。我的观点是我更喜欢