从末尾删除向量中的所有空元素

Posted

技术标签:

【中文标题】从末尾删除向量中的所有空元素【英文标题】:Removing all empty elements in a vector from end 【发布时间】:2018-04-30 13:53:51 【问题描述】:

给定一个std::vector 字符串,删除从末尾开始的所有空元素(等于空字符串或空格)的最佳方法是什么。当找到非空元素时,应该停止删除元素。

我目前的方法,(正在进行中)是这样的:

while (Vec.size() > 0 && (Vec.back().size() == 0 || is_whitespace(Vec.back()))

    Vec.pop_back();

其中is_whitespace 返回一个布尔值,说明字符串是否为空格

我怀疑我的方法会在每次迭代时调整向量的大小,这是次优的。也许通过某种算法可以一步完成。

输入:“A”、“B”、“”、“D”、“E”、“”、“”、“”

期望的输出: "A", "B", " ", "D", "E"

【问题讨论】:

使用std::remove_if @Baum 是的,当然它会改变 size() 成员将返回的内容,但不会调整向量存储的大小。 我看不出这个问题与上面链接的问题重复。我要求从最后删除,并且 remove_if 似乎将迭代器作为参数。在这种情况下使用 remove_if 的示例会很有帮助。 @Baum 当向量的存储空间实际增长时,我们通常会说它已经“调整大小”,而不是“重新容量化”,如果这是一个词的话。 @GoswinvonBrederlow 但是remove_if 会遍历整个向量,这不是 OP 在这里需要的。 【参考方案1】:

由于我乍一看没有找到好的骗子,这里有一个简单的解决方案:

// Helper function to see if string is all whitespace
// Can also be implemented as free-function for readablity and
// reusability of course
auto stringIsWhitespace = [](const auto &str)

    return std::all_of(
        begin(str), end(str), [](unsigned char c)  return std::isspace(c); );
;

// Find first non-whitespace string from the back
auto it = std::find_if_not(rbegin(Vec), rend(Vec), stringIsWhitespace);
// Erase from there to the end
Vec.erase(it.base(), end(Vec));

由于this gotcha,请注意 lambda 中的 unsigned

Live example 感谢@Killzone Kid。

【讨论】:

这绝对是一个更现代的 C++ 解决方案,但请注意,它确实需要两次遍历空白元素。 @MikeBorkland 但另一方面,我们对重复的 pop 使用批量删除操作。特别是对于像char 这样简单的东西,我非常不愿意相信没有基准测试会有不可忽略的性能差异。第二个“迭代”可以实现为对向量的 size 成员的赋值 似乎不适用于字符串向量,据我了解 OP 的要求 @KillzoneKid 啊对;他的代码测试字符而不是字符串,从那里开始。等一下,我会解决的。谢谢。 @BaummitAugen 除了缺少 lambda 的右括号外,它似乎仍然不起作用:( ideone.com/GJ202T【参考方案2】:

这里有一个更好的方法:

for (auto it = Vec.rbegin(); it != Vec.rend() && is_whitespace(*it); )

    it = Vec.erase(it);

一旦遇到非空格或到达向量的开头,它将从末尾开始并停止,以先到者为准。请注意,我不会在 for 循环中增加迭代器。

【讨论】:

auto 在这里选择正确的迭代器吗?你需要一个删除迭代器。

以上是关于从末尾删除向量中的所有空元素的主要内容,如果未能解决你的问题,请参考以下文章

如何删除数组中的所有空数组

如何递归删除PowerShell中的所有空文件夹?

当行不消失时删除data.frame中的所有空列和行

从 SQL Server 中的 XML 中删除所有空节点

如何将默认值 0 赋予 Handsontable 中的所有空单元格?

如何避免 Jaxb XML 中的所有空标签