给定一个向量,擦除元素低于itemsnum

时间:2017-07-02 22:56:59

标签: 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.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;
}

感谢。

3 个答案:

答案 0 :(得分:4)

最好的方法是删除删除习语:

#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;
}

答案 1 :(得分:0)

您的主要问题是第一个for循环。例如,如果results[2]results[3]都是短字符串,则会到达j==2并删除第二个元素 - 这会将所有内容移到一个插槽之后,因此短字符串为{{1现在在results[3]。然后results[2]循环立即将for增加到3,因此您永远不会检查现在为j的第二个短字符串。

第二个递归循环确实照顾&#34;修复&#34;这是正确的,但你是对的,这很愚蠢。

std::remove_if非常适合这一点。请注意,它实际上并没有从向量本身中删除任何内容,它只是向下滑动元素并在末尾留下垃圾,因此我们之后调用results[2]将向量缩小到正确的大小:

vector::erase

你可能想要考虑通过非const引用来获取向量,而不是通过副本传递然后返回另一个修改过的向量。

答案 2 :(得分:0)

擦除删除成语有效,但我个人更喜欢即使是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;
}