如何从cpp中的std :: list中删除每一个元素?

Sha*_*sif 1 c++

我正在尝试从std :: list中删除每个第二个元素,但是当我运行erase()时,我遇到了段错误(核心转储).

#include <bits/stdc++.h>

using namespace std;

int main()
{
    list <int> num_list;
    list <int> :: iterator it;
    num_list.push_back(1);
    num_list.push_back(2);
    num_list.push_back(3);
    num_list.push_back(4);
    num_list.push_back(5);
    cout << num_list.size() << endl;
    it = num_list.begin();
    advance(it, 1);
    for(it; it != num_list.end(); advance(it, 2)) {
        num_list.erase(it);
    }
    for(it = num_list.begin(); it != num_list.end(); ++it) {
        cout << *it << " ";
    } 
    cout << endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

Pet*_*ter 9

从第二项开始:next(num_list.begin(), 1).该erase方法将迭代器返回到已删除项的下一项.所以你可以使用just ++运算符来执行第2步.

int main()
{
    list<int> num_list;
    num_list.push_back(1);
    num_list.push_back(2);
    num_list.push_back(3);
    num_list.push_back(4);
    num_list.push_back(5);
    cout << num_list.size() << endl;

    for (auto it = next(num_list.begin(), 1); it != num_list.end();) {
        it = num_list.erase(it);
        if (it != num_list.end())
            ++it;
    }
    for (auto it = num_list.begin(); it != num_list.end(); ++it) {
        cout << *it << " ";
    }
    cout << endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)


Fur*_*ish 7

为了解释为什么你的方法不起作用,请参阅Stepan Lechner的回答.

使用std::remove_if和lambda表达式完全不同的方法:

int main() {
    std::list<int> ints{1, 2, 3, 4, 5};

    auto position = std::remove_if(ints.begin(), ints.end(),
            [counter = 0](const auto x) mutable {
        return ++counter % 2 == 0;
    });

    ints.erase(position, ints.end());

    for(const auto x : ints) {
        std::cout << x << ' ';
    }
}
Run Code Online (Sandbox Code Playgroud)

std::remove_iferase方法调用配对,是用于从范围中移除特定元素算法.在这里,就有点难度的-我们要删除所有的第二个元素,所以我们需要一个断言,这将返回true只对列表中的偶数位置.我们使用使用lambda init capture初始化的成员计数器来实现它.

编辑:正如MSalters在评论中正确陈述的那样,使用std::list::remove_if是一种优秀的erase-remove成语解决方案<algorithm>.它利用了内部std::list实现,而且输入的方式不那么尴尬:

// *ints* being the list itself
ints.remove_if([counter = 0](const auto x) mutable {
    return ++counter % 2 == 0;
});
Run Code Online (Sandbox Code Playgroud)

而不是原来的:

auto position = std::remove_if(ints.begin(), ints.end(),
        [counter = 0](const auto x) mutable {
    return ++counter % 2 == 0;
});

ints.erase(position, ints.end());
Run Code Online (Sandbox Code Playgroud)

  • 有一个`std :: list :: remove_if`,它不需要`.erase`. (3认同)