目的:去掉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
请教下一为何会漏掉某些字符?
查手册找到两句话
All iterators and references are invalidated, unless the erased elements are at the end or the beginning of the container, in which case only the iterators and references to the erased elements are invalidated.
Iterator following the last removed element. If the iterator pos refers to the last element, the
end()
iterator is returned.
问题基本解决了,谢谢大家。
1
xc77 2015-11-06 13:55:05 +08:00
string.erase(it); 迭代器失效
|
2
xujunfu 2015-11-06 13:56:00 +08:00
string.erase(it);删除操作迭代器很有可能失效的了哦
|
3
womaomao 2015-11-06 13:58:00 +08:00
erase 的时候,迭代器已经指向下一个迭代位置了,你这个循环还是会++it ,所以跳过一个。下面应该可以了
for (deque<char>::iterator it = string.begin(); it != string.end(); ) { if ('a' <= *it && *it <= 'z') { ++it; continue; } else if ('A' <= *it && *it <= 'Z') { *it = tolower(*it); ++it; } else string.erase(it); } |
4
firemiles 2015-11-06 14:56:33 +08:00
再补充下,你头文件的引用为什么不用<>
|
5
abscon 2015-11-06 16:22:18 +08:00
为何选用 deque 而不是 list 。我觉得你的“目的”(去掉 std::deque 中不符合条件的元素)好别扭。
几点建议: 包含标准头文件时请使用尖括号而不是引号 可以用 auto 来代替 deque<char>::iterator 可以使用 islower 和 isupper 来判断大小写 #include <cctype> getchar 在 <cstdio> 里。而且你输入用 getchar ,输出用 cout ,感觉是西装配短裤。 deque<char> string 这个变量名取得相当糟糕,与 std::string 重名了 |
6
abscon 2015-11-06 16:29:13 +08:00
@abscon 呃,考虑到你要处理的是字符串,用 list 其实也挺奇怪的。你为何不用 std::string 或者 vector<char> 。另外一定要 **原地** 做这件事情么? 不能从原容器复制到新容器,去掉非字母字符,转换大写字母到小写?
|
7
bazingaterry OP @abscon 谢谢回复!
1. 只是昨晚 Coding 遇到这样的问题,我举个例子说出来,实际上并不是处理字符。 2. 代码是临时打的,新手可能不规范,望包涵, Sublime Text 默认是用""而不是<>我没改过来。 |
8
bazingaterry OP @abscon auto 我也很喜欢在平时学校的项目中使用,但是我学校 OJ 不支持 C++11 ,所以平时基本不能用。
|
9
bazingaterry OP |
10
bazingaterry OP |
11
xc77 2015-11-06 17:23:07 +08:00
@bazingaterry erase 后会指向 deque 的下一个位置, 所以你需要 it = string.erase(it),来保存新的位置
前面成功,可能是因为在处理到后面是内存进行了重新分配 |
12
bazingaterry OP @xc77 明白了!!谢谢!!
|
13
colatin 2015-11-06 17:43:47 +08:00
改成 erase(it++)试试看
|
14
hqs123 2015-11-06 23:33:13 +08:00
C++不熟,我也来学习下 多谢分享。
|
15
yhylord 2015-11-07 09:11:09 +08:00
是强制需要用 std::deque 么?我觉得读入,判断,输出就已经足够了,不需要中间储存的一步。
|
17
kxcd 2015-11-07 10:59:54 +08:00
iterator erase (iterator position);
iterator erase (iterator first, iterator last); erase 返回值为 iterator , it = string.erase(it); ps: string 变量命名,噗... |