要求:处理一个字符串,删除字符串中多余的空格、水平制表符和空行,并满足下列要求:
(1)对原字符串只能进行一次扫描。
(2)不允许申请新的空间。
(3)处理后的字符串的首尾不能有空格、制表符和空行。
(4)如果原字符串中连续出现空格和水平制表符,则处理后的字符串只需存储一个空格。
(5)如果原字符串中连续出现空格、水平制表符和空行,则处理后的字符串只需存储一个空行。
C语言实现代码如下(该代码经过garbageMan提醒后进行了更改):
1 //state 0: 初始状态 2 //state 1: 前一个字符是'\n'(非初始状态) 3 //state 2: 前一个字符是空格(非初始状态) 4 //state 3: 前一个字符既不是空格也不是'\n' 5 void remove_extra_space(char *str) 6 { 7 int state = 0; //当前状态 8 int i = 0; //读入位置 9 int j = 0; //输出位置 10 11 for(; str[i] != 0; ++i) 12 { 13 if(str[i] == ' ' || str[i] == '\t') 14 { 15 if(state == 0 || state == 1 || state == 2) 16 continue; 17 else if(state == 3) 18 { 19 str[j++] = ' ' ; 20 state = 2; 21 } 22 } 23 else if(str[i] == '\n') 24 { 25 if(state == 0 || state == 1) 26 continue; 27 else if(state == 2) 28 { 29 str[j - 1] = '\n'; 30 state = 1; 31 } 32 else if(state == 3) 33 { 34 str[j++] = '\n'; 35 state = 1; 36 } 37 } 38 else 39 { 40 str[j++] = str[i]; 41 state = 3; 42 } 43 } 44 if(state == 1 || state == 2) 45 --j; 46 str[j] = 0; 47 }
参照garbageMan的思路和playerc的代码更改为使用指针的版本(推荐):
1 void remove_extra_space(char *str) 2 { 3 char *sp = str; 4 char *prev = 0; 5 6 while(*str && (*str == ' ' || *str == '\n' || *str =='\t')) 7 ++str; 8 9 for(; *str; ++str) 10 { 11 switch (*str) 12 { 13 case '\t': *str = ' '; 14 case ' ' : 15 if (*prev == '\n' || *prev ==' ') 16 continue; 17 break; 18 19 case '\n': 20 if (*prev == '\n') 21 continue; 22 else if (*prev == ' ') 23 { 24 *prev = '\n'; 25 continue; 26 } 27 break; 28 } 29 30 prev = sp; 31 *sp++ = *str; 32 } 33 34 if(prev && *prev && (*prev == ' ' || *prev == '\n')) 35 --sp; 36 *sp = 0; 37 }
参考playerc所写代码:http://www.cnblogs.com/playerc/p/3217355.html
最后,对所有提供宝贵意见的朋友表示感谢!