如何在while循环中使用.erase()?

时间:2017-10-21 19:58:07

标签: c++

背景: 这是在向量中逐位存储的数字加1的程序。

前面有0的数字被允许作为输入但不作为输出。 例如:0123& 123都是有效的输入     但是0124是无效的输出     124是有效输出

问题: 我想使用erase()删除输出向量前面的0,直到使用代码底部的while循环找到非零值。 但是编译器返回垃圾值。另一个在线编译器给出了分段错误。 在没有while循环的情况下编译时,其余代码工作正常。

#include <iostream>
#include<vector>
using namespace std;
int main()
{
    vector<int> A = { 9, 9, 9 };
    A.insert(A.begin(), 0); /*--last carry may nonzero so new digit -*/
    vector<int>::reverse_iterator it;
    int c = 1;
    for (it = A.rbegin(); it != A.rend(); it++) /*----finds and adds carry---*/
    {
        int d = *it;
        d = d + c;
        c = d / 10;
        if (c == 0)
            *it = d;
        else
        {
            d = d % 10;
            *it = d;
        }

    }
    vector<int>::iterator iss;
    iss = A.begin();

问题循环开始

    while (*iss == 0) /*----------------problem----------------*/
    {
        iss = A.erase(iss);
    }

循环结束

    for (int i = 0; i < A.size(); i++)
    {
        cout << A[i];
    }
}

3 个答案:

答案 0 :(得分:1)

你所写的内容几乎是正确的。应该对结束迭代器进行额外的检查。

while(iss != A.end() && *iss == 0) {
    iss = A.erase(iss);
}

但是,可以实现它以使算法具有更好的性能:

while(iss != A.end() && *iss == 0) {
    ++iss;
}
A.erase(A.begin(), iss);

答案 1 :(得分:0)

不清楚你在哪里看到垃圾,但你错过了检查迭代器是否有效,例如while(iss != A.end() && *iss==0)

答案 2 :(得分:0)

不是从向量中删除项目,而是(从复杂性的角度来看)将项目移动到另一个向量,移动对象以保持另一个向量,这几乎总是优选的。这也有更好的性能(从矢量的头部删除将在最好的情况下移动所有其他对象):

void remove_zeroes(std::vector<int>& v) {
    std::vector<int> saved;
    auto begin = std::find_if(v.begin(),v.end(),[](int x){ return x != 0; });
    for(auto it = begin; it != v.end(); it++) {
        saved.push_back(std::move(*it));
    }
    v.swap(saved);
}

虽然在这种情况下它只相当于使用std::vector的范围擦除方法,它将两个迭代器作为参数(如其他答案所示),如果要删除的元素不是&#39,这种技术可能会很有用。 ; t在一个连续的范围内。