删除字符串中的数字并压缩字符串
2013-08-31 20:27 youxin 阅读(2109) 评论(0) 编辑 收藏 举报题目:删除字符串中的数字并压缩字符串 。如字符串”abc123de4fg56”处理后变为”abcdefg”。注意空间和效率。
分析:可用两个索引指向字符串的开头,一个向后推进作为循环条件,另一个跨过数据向后推进。达到消除数据及压缩操作。
一快一慢,可称为快慢消除法。
/*************************************************************************************** 删除字符串中的数字并压缩字符串 题目:删除字符串中的数字并压缩字符串 。 如字符串”abc123de4fg56”处理后变为”abcdefg”。注意空间和效率。 分析:可用两个索引指向字符串的开头, 一个向后推进作为循环条件,另一个跨过数据向后推进。达到消除数据及压缩操作。 一快一慢,可称为快慢消除法。 *****************************************************************************************/ #include <stdio.h> #define USE 1 #if USE void ddc(char *s) { int i = 0; int j = 0; while(s[i]) { if(s[i]<'0' || s[i]>'9') { s[j++] = s[i]; } i++; } s[j] = '\0'; } #else char *ddc(char *s) { char *p = s; char *res = p; while(*s) { if(*s < '0' || *s > '9') { *p++ = *s; } s++; } *p = '\0'; return res; } #endif int main(void) { //char *str = "abc123de4fg56"; segmentation fault。 char str[] = "abc123de4fg56"; #if USE ddc(str); printf("result is %s\n",str); #else printf("result is %s\n",ddc(str)); #endif return 0; }
当参数定义为char *str = "abc123de4fg56" 时,会发生SEGMENTATION FAULT。
当参数定义为char str[] = "abc123de4fg56" 时,会正常运行。
合理的解释是,参数定义char *str = "abc123de4fg56" 时,表明str指向的是一个字符串常量,不能重写。
而移动过程中会发生读写操作,所以会发生SEGMENTATION FAULT。 而参数定义为char str[] = "abc123de4fg56"
时是定义的一个字符指针,初始化为 "abc123de4fg56" 。可以读写。所以会正常运行。
有一道类似的题目,也是快慢消除法:
一个字符串只包含a和b,现在要求对这个字符串进行排序,要求将所有的a放在b的前面
char * Sort(char * str) { char * p1 = str; while(*p1=='a') { ++p1; } char * p2 = p1; while(*p2!='\0') { if(*p2=='a') { *p1= 'a'; *p2= 'b'; ++p1; } ++p2; } return str; }
我另外写的代码:
#include<iostream> using namespace std; void sortStr(char *s) { int i,j; j=0; while(s[j]=='a') { j++;//j作为存储新数据的标志点 } i=j; while(s[i]!='\0') { if(s[i]=='a') { swap(s[i],s[j]); //s[j]='a'; 和上面的swap作用等同 //s[i]='b'; j++; } i++; } } int main() { char str[]="ababaaa"; sortStr(str); cout<<str; }
思路跟上面的一样,j指向b,首先必须:
while(s[j]=='a') { j++;//j作为存储新数据的标志点 }
这里我们必须先把j指向第一个不是a,即b。
然后在第二个while里面我们每次把i向前推进,如果i是a。把s[i]和s[j]交换。
示例:
ababaaa
第一次while后j指向第一个b,j=1;
i=2时,s[2]=a;交换,变成了aabbaaa
i=3,
i=4; s[4]=a; 把s[2]和s[4]交换。变成了aaabbaa
i=5;把s[5]和s[3]交换,变成了aaaabba
i=6; aaaaabb
可以看到,j始终代表从字符串范围[0,j]个a。
这种快慢消除法的思想可以用在很多方面:
如以前写的,在一个串中消除另一个串中的字符:www.cnblogs.com/youxin/p/3294150.html
面试题:删除字符串中多余的空格。
给定字符串,删除开始和结尾处的空格,并将中间的多个连续的空格合并成一个。
比如 “ I like http://hi.baidu.com/mianshiti ” 会变成 "I like http://hi.baidu.com/mianshiti"。
算法的文字描述如下:第一步:初始化:用i指针控制输出开始为0,j指针从0处开始扫描;
第二步:左边空格:当j遇见第一个不是空格的字符,赋给i处.i指向下一位;
第三步:中间以及后面空格:继续扫描,如果遇见空格则赋给i处,i指向下一位,后面空格就忽略直到下一个不是空格字符赋给i处,i指向下一位。
第四步:给字符串加一个'\0'并且返回。算法结束。
#include<iostream> using namespace std; char *deleteSurplusSpace(char * str) { char *p=str; int j=0; //delete left space while(*p==' ') { p++; } while(*p) { if(*p!=' ') { str[j++]=*p; } else { while(*p==' ') { p++; } str[j++]=' '; p--;//这里很重要,因为后面p++; } p++; } str[j]='\0'; return str; } int main() { char str[]=" A B C DE "; char *p=deleteSurplusSpace(str); cout<<p; }
输出:
A B C DE 请按任意键继续. . .
虽然我知道用快慢消除法,可是程序写起来不容易写对,很多细节值得注意。
相似题:
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步