In fact, I used to encounter the erase problem of vector when I was writing code. I just forgot it again.
This is probably the case when I went to the manheng digital interview and asked the following questions after the program runs:
Vector <int> A; <br/>. push_back (1); <br/>. push_back (2); <br/>. push_back (4); <br/>. push_back (3); <br/> for (vector <int>: iterator itor =. begin (); itor! =. End (); itor ++) <br/>{< br/> If (* itor = 2) <br/>{< br/>. erase (itor); <br/>}< br/>}
The problem is that after the itor is erased, The for loop calls the itor again. The correct method is as follows:
Vector <int> A; <br/>. push_back (1); <br/>. push_back (2); <br/>. push_back (4); <br/>. push_back (3); <br/> for (vector <int>: iterator itor =. begin (); itor! =. End ();) <br/>{< br/> If (* itor = 2) <br/>{< br/> itor =. erase (itor); <br/>}< br/> else <br/>{< br/> itor ++; <br/>}< br/>}
The following article provides a good description of this issue.
Http://blog.csdn.net/guafeng/archive/2008/06/20/2570313.aspx
Error in erase operation of STL Vector
A boss said there is a blog on csdn ("On STL vector erase operation", address is: http://blog.csdn.net/tingya/archive/2007/12/28/1998442.aspx) Black strange, holding the odd mentality of hunting, occasionally go together ha lively, I found a problem and reported it to you.
The following code is incorrect:
Vector <unsigned short> m_uintvector;
M_uintvector.push_back (10 );
M_uintvector.push_back (20 );
M_uintvector.push_back (30 );
Vector <unsigned short >:: iterator itr;
Itr = STD: Find (m_uintvector.begin (), m_uintvector.end (), 20 );
M_uintvector.erase (itr );
The author provides the "correct" code:
Vector <unsigned short> m_uintvector;
M_uintvector.push_back (10 );
M_uintvector.push_back (20 );
M_uintvector.push_back (30 );
Vector <unsigned short >:: iterator itr;
Itr = STD: Find (m_uintvector.begin (), m_uintvector.end (), 20 );
// Delete an element
Int diff = itr-m_uintvector.begin ();
M_uintvector.erase (m_uintvector.begin () + diff );
I don't see where the "correct" code is? Let's not consider whether the code is correct. From the perspective of the amount of code, it is significantly increased; from the perspective of code universality, Code such as iterator + diff is only applicable to random iterators, for list, non-random iterators, such as map, cannot be used. I think the first method is more beautiful and generic. As for the code correctness, I tested it and worked very well.
I guess the author did not fully describe the actual working environment here, and some restrictions should not be listed. I Googled and found the following situation:
Void main ()
{
Vector <int> member;
Member. push_back (1 );
Member. push_back (2 );
Member. push_back (2 );
Member. push_back (3 );
Member. push_back (1 );
Member. push_back (2 );
Member. push_back (4 );
Vector <int>: iterator ITER;
For (iter = member. Begin ();
ITER! = Member. End (); ITER ++)
Cout <* ITER <Endl;
Cout <"Do erase --------" <Endl;
For (iter = member. Begin ();
ITER! = Member. End (); ITER ++)
{
If (* iter = 2)
{
Member. Erase (ITER );
}
}
For (iter = member. Begin ();
ITER! = Member. End (); ITER ++)
Cout <* ITER <Endl;
}
At first glance, isn't this the same as the first method mentioned above? It seems that there is no problem. However, you should note that after calling erase, you can go back to the for loop and continue to use the iterator and execute the ++ operation.
Okay. Let's review the description of the erase function:
Iterator erase (iterator position );
Iterator erase (iterator first, iterator last );
Now we only focus on the side effects and return values after function execution. After the function is called, all iterators pointing to position and first become invalid. The returned value is an iterator pointing to the elements following the last deleted element. Therefore, the ITER in the code above becomes invalid after erase is called. I tested it in vs2005 and did crash in the ++ operation.
To solve this problem, we only need to discard the original iterator and use the return value. The Code is as follows:
For (iter = member. Begin (); iter! = Member. End ();)
{
If (* iter = 2)
{
Iter = member. Erase (ITER );
}
Else
{
ITER ++;
}
}
There are still many such articles on the Internet that are not quite clear, such as "how to delete elements in STD: Vector ?" To delete the element in STD: vector, use find () Generic Algorithm in a regular way. If find () is found, the iterator is returned, if it cannot be found, it will return a vector. end (). This method is much cleaner than for loop.
View the Code provided by him:
// Compile OK, but run-time error !!
// For (STD: vector <int >:: iterator iter = ivec. Begin ();
// Iter! = Ivec. End (); ++ ITER ){
// If (* iter = 8 ){
// Ivec. Erase (ITER );
//}
//}
// This is a right way to do it.
STD: vector <int >:: iterator iter = find (ivec. Begin (), ivec. End (), 8 );
If (ITER! = Ivec. End ()){
Ivec. Erase (ITER );
}
So let's look at the articles on the Internet. It's best to look at it as a novel and explore other people's technical life. Do not take it seriously if it's true or not. Otherwise, the next generation of Don Quixote will be born.