如何将 remove_if 与 !函数的(非函数的)

Posted

技术标签:

【中文标题】如何将 remove_if 与 !函数的(非函数的)【英文标题】:How to use remove_if with the ! of a function (the not of a function) 【发布时间】:2012-04-27 19:07:10 【问题描述】:

基本上,我正在尝试这样做:

word.resize(remove_if(word.begin(), word.end(), not1(isalpha())) - word.begin());

我知道你只是声明自己的函数并传递它的丑陋解决方法。但是有没有办法让这个工作?我收到消息“函数调用中的参数太少”,isalpha 函数下方有一条红线。

【问题讨论】:

您可能想添加一个示例来说明您要完成的工作,因为我不明白您的问题在问什么。 您在寻找cplusplus.com/reference/std/functional/not1 吗? paring resize with remove 工作,但通常你应该使用erase word.erase(remove_if(...));,因为它更通用,不需要额外的- word.begin() 【参考方案1】:

在 C++03 中,您通常会使用以下内容:

std::not1(std::ptr_fun(isalpha))

在 C++11 中,您更经常使用 lambda:

word.resize(
   remove_if(word.begin(), word.end(), 
             [](char ch)return !isalpha(ch);) -word.begin());

编辑:您可能还想阅读昨天在代码审查中提出的similar question。它并不完全相同,但足够相似,可能会引起人们的兴趣(它不是询问!isalpha,而是询问从字符串中删除非字母字符)。

Edit2:做一个快速测试,这似乎有效:

#include <algorithm>
#include <string>
#include <iostream>
#include <iterator>
#include <ctype.h>

template <class T>
T gen_random(size_t len) 
    T x;
    x.reserve(len);

    std::generate_n(std::back_inserter(x), len, rand);
    return x;


template <class Container>
void test2(Container &input) 
    input.resize(
        std::remove_if(input.begin(), input.end(), 
        [](char ch)return !isalpha(ch);) -input.begin());


int main()

    std::string input(gen_random<std::string>(100));
    std::cout << "Input: \n" << input << "\n\n";

    input.resize(
        std::remove_if(input.begin(), input.end(), 
        [](char ch)return !isalpha(ch);) -input.begin());

    std::cout << "Result: " << input << "\n";

    return 0;

至少当我运行它时,我得到:

Input:
ë♠╖G▐│↕M╚C╗ïª▼♥Z       8%▼]╘╦ⁿû⌡E;‼
∟█«2 ÜPε@x6²↕I2÷₧I▄¡O¶≥D@f╨k─0╖2;í"÷"æ¥

Result: lRIGMCZEPxIIODfk

从外观上看,我生成的随机输入至少包含一个回车符,因此输入中的前几个字符在输出中不可见。我检查了从“G”开始的一对,然后检查了最后一对,但一切似乎都很好。

【讨论】:

我测试了代码,但是这行代码让我的话变成了“”。这个词是“生产”。这是我使用的代码: word.resize(remove_if(word.begin(), word.end(), [](char letter)return !isalpha(letter);) - word.end());您是否发现任何明显的问题? 在这种情况下,使用函数适配器可能比 lambda 更可取。不需要仅仅因为我们拥有它们就将所有内容都强制转换为 lambda。 @user904963 是的,这有问题。你在那里有- end(),因此返回值将始终为0或负数。你应该使用erase 而不是remove 来避免这种问题。 @user904963 word.erase(remove_if(begin(word),end(word),not1(std::ptr_fun(isalpha)))); @user904963:是的。我应该补充一点,不过我大多同意 bames53 ——为此,erase 可能比resize 更有意义。

以上是关于如何将 remove_if 与 !函数的(非函数的)的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 remove_if 从向量中删除元素

remove_if erase

第十三篇:成员函数与非成员函数的选择

有没有更好的替代 std::remove_if 从向量中删除元素的方法?

如何在 C# 中启动一个与非异步函数异步的函数? [复制]

特定容器算法