为什么要删除空间?c++ .erase()

Why is deleting the space? c++ .erase()

提问人:F. Andrés 提问时间:5/19/2023 最后编辑:Remy LebeauF. Andrés 更新时间:5/19/2023 访问量:105

问:

我正在解决代码战中的一个套路,您必须删除感叹号“!

但是,当使用 时,它也会删除空间。我不明白它是如何连续删除三个“!”的。.erase()

这是给我带来问题的字符串:

"Hi! Hello!"

调试,它去:

"HiHello!"

它吃掉了空间,最终成为:

"HiHello"

这个有效,但我不明白在调试它时为什么不出现更多:

"Hello World!!!"

前往:

"Hello World"

我不明白为什么它没有显示为 and"Hello World!!""Hello World!"

我以前用于拆分字符串。我明白了,其中 是字符串的开头 包含 和 结尾 是 排除 的,也是 的成员函数。.erase().erase(first,second)firstsecond.erase()std::string

--奖金-- 我尝试使用并同样工作。.erase(pos,pos)

这是我的代码:

#include <string>

std::string removeExclamationMarks(std::string str){
    std::string remove{ "!" };
    std::cerr << str << '\n';
    size_t pos{};
    while( (pos = str.find(remove)) != std::string::npos ){
        std::cerr << pos << '\n';
        str.erase(pos, pos + remove.length());
        std::cerr << str << '\n';
    }
    std::cerr << "END\n";
    return str;
}
C++ 字符串 while-loop 字符 擦除

评论

0赞 user17732522 5/19/2023
"我理解 .erase(first,second),其中第一个是字符串的开头(包含),第二个是结束(排除)“:如果您通过索引而不是迭代器擦除,那是错误的。再次阅读您的参考资料。std::string::erase
4赞 Igor Tandetnik 5/19/2023
整个事情可以在一行中完成:.这也更有效 - 字符串的长度是线性的,而你的字符串是二次的。str.erase(std::remove(str.begin(), str.end(), '!'), str.end());
2赞 PaulMcKenzie 5/19/2023
@OP -- 至于为什么使用更有效率,实际上并没有删除任何东西 -- 相反,要删除的项目被复制到字符串的后面(实际上不是复制的,而是垃圾到字符串的后面)。然后返回一个指向垃圾区域的迭代器。然后擦除从该迭代器开始的所有内容。std::removeremoveremoveerase
0赞 Pete Becker 5/19/2023
问题中的代码在找到匹配项后,会在字符串的开头重新开始搜索。无需再次搜索字符串的前面;那里没有任何感叹号。因此,在删除感叹号的位置重新开始搜索:。此外,通过调用将查找单个字符而不是包含单个字符的 C 样式字符串,但正如 @PaulMcKenzie 指出的那样,这仍然会进行许多不必要的洗牌。pos = str.find(remove, pos)char remove = ‘,’find

答:

4赞 Vlad from Moscow 5/19/2023 #1

该方法的此调用不正确erase

str.erase(pos, pos + remove.length());

第二个参数指定要擦除的元素数。

所以你需要写

str.erase(pos, remove.length());

请注意,如果你的编译器支持 C++20,那么你可以编写

std::erase( str, '!' );