C++使用STL遇到的问题
阿神
阿神 2017-04-17 13:02:06
0
3
608

目的:去掉std::deque中不符合条件的元素,在下面的代码中,是把大写转成小写,把其他符号去掉。

#include "iostream"
#include "deque"
using namespace std;

int main ()
{
    deque<char> string;
    char ch;
    while((ch = getchar()) != EOF)
        string.push_back(ch);
    
    for (deque<char>::iterator it = string.begin(); it != string.end(); ++it)
    {
        if ('a' <= *it && *it <= 'z')
            continue;
        else if ('A' <= *it && *it <= 'Z')
            *it = tolower(*it);
        else
            string.erase(it);
    }
    
    while (!string.empty())
    {
        cout << string.front();
        string.pop_front();
    }
}

输入:

das ;ds;a ;das; d;as
d;as ;das; ;das

输出:

dasdsadasdasdas;das das

请教下一为何会漏掉某些字符?

阿神
阿神

闭关修行中......

reply all(3)
Peter_Zhu

The iterator is invalid. To remove unmatched elements in the container, you can first move remove_if to the end of the container and then call the container's own erase to delete them in batches

  using namespace std;

  deque<char> in;
  transform(istream_iterator<char>(cin), istream_iterator<char>(), back_inserter(in), tolower);
  in.erase(remove_if(begin(in), end(in), not1(ptr_fun(isalpha))), end(in));
  copy(begin(in), end(in), ostream_iterator<char>(cout));

If you don’t need to delete it, you can do this

  using namespace std;

  deque<char> in;
  transform(istream_iterator<char>(cin), istream_iterator<char>(), back_inserter(in), tolower);
  copy(begin(in), remove_if(begin(in), end(in), not1(ptr_fun(isalpha))), ostream_iterator<char>(cout));

The return value of remove_if and remove is the starting position of the element that can be deleted

Ty80

Let me explain to you, in the place of two numbers, if it now points to the first one; then it meets the conditions for deletion erase(it). At this time it++, but at this time it no longer points to the second; but the following d. Because when you erase(it), the pointer after it will move forward. it already points to the second one; how can you still point to the second one in it++? That's why you use spaces and semicolons together. So your program itself is wrong, because it does not check every character. Every time you perform an erase(it) operation, the following characters will not be checked regardless of whether they are legal or not. For the correct writing method, you can refer to the following (for reference only):

deque<char>::iterator it = string.begin();
while(it!= string.end() )
{
     if ('a' <= *it && *it <= 'z')
        continue;
    else if ('A' <= *it && *it <= 'Z')
        *it = tolower(*it);
    else 
    {
        string.erase(it);
        continue;
    }
    it++;    
}
左手右手慢动作

After calling the erase function, the original iterator it becomes invalid, and the ++ operation on it is unpredictable.

Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template