简体   繁体   English

在迭代过程中从向量中擦除元素

[英]Erasing an element from the vector during iteration c++

I wrote this method to find the minor of a sparse matrix: 我编写了此方法来查找稀疏矩阵的次要部分:

SpMatrixVec SparseMatrix::minor(SpMatrixVec matrix, int col) const{

    SpMatrixVec::iterator it = matrix.begin();

    int currRow = it->getRow();

    int currCol = col;

    while(it != matrix.end()) {

        if(it->getRow() == currRow || it->getCol() == currCol){
            matrix.erase(it);
        }
        // if we have deleted an element in the array, it doesn't advance the
        // iterator and size() will be decreased by one.
        else{   
            it++;
        }

    }

    // now, we alter the cells of the minor matrix to be of proper coordinates.
    // this is necessary for sign computation (+/-) in the determinant recursive
    // formula of detHelper(), since the minor matrix non-zero elements are now
    // in different coordinates. The row is always decreased by one, since we
    // work witht he first line, and the col is decreased by one if the element
    // was located after 'col' (which this function receives as a parameter).

    //change the cells of the minor to their proper coordinates.
    for(it = matrix.begin(); it != matrix.end(); it++){

        it->setRow(it->getRow()-1);

        int newY;
        newY = (it->getCol() > col) ? it->getCol() + 1 : it->getCol();

        it->setCol(newY);
    }
    return matrix;

}

Now, i'm probably doing something wrong, because when reaching the second interation of the while loop, the program crashes. 现在,我可能做错了,因为到达while循环的第二次插入while ,程序崩溃了。 The basic idea was to go over the vector, and see if it is the relevant coordinate, and if so - to delete it. 基本思想是遍历向量,然后查看它是否是相关坐标,如果是,则删除它。 I increment the iterator only if there was no deletion (and in this case, the vector should update the iterator to be pointing the next element..unless i got these things wrong). 仅在没有删除的情况下,我才递增迭代器(在这种情况下,矢量应更新迭代器以指向下一个元素。除非我弄错了这些东西)。

Where is the problem? 问题出在哪儿?

Thanks a lot. 非常感谢。

erase() invalidates your iterator. erase()使您的迭代器无效。

You must update it using the return value of erase() for the loop to work: 您必须使用erase()的返回值更新it ,以使循环正常工作:

while(it != matrix.end()) {

    if(it->getRow() == currRow || it->getCol() == currCol){
        //matrix.erase(it);
        it = matrix.erase(it); // Here is the change
    }
    // if we have deleted an element in the array, it doesn't advance the
    // iterator and size() will be decreased by one.
    else{   
        //it++;
        ++it; // ++i is usually faster than i++. It's a good habit to use it.
    }

}

erase invalidates your iterator. erase会使您的迭代器无效。 Do it = matrix.erase(it) instead. 改为it = matrix.erase(it)

You can't change a collection while you're iterating between its elements. 在元素之间进行迭代时,无法更改集合。 Use another temp collection to store the partial results. 使用另一个临时集合来存储部分结果。

edit: Even better, use a functor to delete elements: remove_if You write the condition. 编辑:更好的是,使用函子删除元素: remove_if您编写条件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM