输入2个字符串S1和S2,要求删除字符串S1中出现的所有子串S2,即结果字符串中不能包含S2。
提示:输入数据的设计使得不可能出现输出为空的情况。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
/*
* 输入2个字符串S1和S2,要求删除字符串S1中出现的所有子串S2,
* 即结果字符串中不能包含S2。
* 提示:输入数据的设计使得不可能出现输出为空的情况。
*/
char* str_remove_key(const char* src,const char* key);
int main(void)
{
char *src = "ccaabbccddcckkccmmccppccqqccxx";
//char *src = "xxww";
char* p =str_remove_key(src,"cc");
printf("%s\n",p);
free(p);
return 0;
}
char* str_remove_key(const char* src,const char* key)
{
int keyLen = strlen(key);
// cc aabb ccddcckkccmmccppccqqccxx
char *xx = (char*)malloc(strlen(src)+1);
char *dest = (char*)malloc(strlen(src)+1);
char *xtemp = xx;
int lastIndex = 0;
int i=0;
while((xx = strstr(src,key))!=NULL)
{
int len = xx - src;
if(len){
for(i=0;i<len;i++){
dest[lastIndex+i] = *(src+i);
}
lastIndex += i;
// printf("lastIndex = %d\n",lastIndex);
// dest[lastIndex] = '\0';
}else{
// do nothing !
}
// printf("src = %s , dest = %s\n",src,dest);
xx +=keyLen;
src = xx;
}
dest[lastIndex] = '\0';
strcat(dest,src);
// printf("-------------- src = %s , dest = %s\n",src,dest);
free(xtemp);
return dest;
}
整体思路如下:
- 用
strstr()函数来不断查找子串的位置;然后保存子串前面的字符集;然后让子串丢弃前面的关键子串。并改变src为返回的子串;不断查找,直到src中没有子串了为止。
strstr(“abcd”,”ab”) –> “abcd”
strstr(“abcd”,”bc”) –> “bcd”
上面这两个栗子足以说明,为什么要让strstr()得到的返回值去丢弃前面的关键子串了。
步骤如下:
首先定义返回值
char* dest,因为不知道会是多大,但是最大就是和src大小相同。于是char *dest = (char*)malloc(strlen(src)+1);定义查找返回的子串
char *xx。因为也不知道多大,但最大也就和src相同。于是char *xx = (char*)malloc(strlen(src)+1);。同时定义一个临时指针xtemp,指向当前的定义的xx(为了后续的free(xtemp))。最关键的一步:定义
dest的当前需要移动到哪。这里使用了两个变量来共同定义的。分别是lastIndex与i。- 这里为什么要定义两个变量呢?不显得多余吗?
- 答: 注意:这里的
i是要给后续的前字符串用的。因为前字符串是一个一个字符放入到dest中的。i是每次查找之后,被strstr函数丢弃的子串需要的索引。而lastIndex呢,是要记录dest现在的可用空间索引。所以,每次增加一个字符到dest,实际上是应该存放到lastIndex + i所指的位置的空间里面的。
- 然后就是循环查找关键子串是否存在于
src中,使用的就是库函数strstr(src,key)。该函数的特点是,找到了,就返回当前key的位置(指针)。找不到就返回NULL。
- 循环给
xx赋值,只要xx不为NULL就获取被丢弃的长度int len = xx-src。判断len,如果len>0,说明前面有被丢弃的字符串。那么,就通过一个for循环取src所指的内容*(src+i)并存放到dest对应的位置*dest[lastIndex+i]。for结束,就给lastIndex再次赋值:lastIndex = i;因为这时候的i的位置刚好是下次dest应该存放内容的位置。比如:dest现在是“abcd”,那么,这时候就该把lastIndex设置为4。因为下次就应该存放新的内容到(dest+4)的位置上。 - 这时候,里面的事情并没有结束。这时候,也有一件重要的事情,就是移动指针
xx到strlen(key)的后面。也就是丢弃本次查询到的关键子串。也就要xx += strlen(key);,然后src = xx;。这一步是改变循环状态。否则就会死循环,并且不能顺利获取下次查询丢弃的内容了。 - 在循环结束之后,(即使是从来没有进入过循环)。给
dest[lastIndex]赋值为\0。并执行strcat(dest,src)的操作。
- 为什么要执行这一步呢?
- 因为,如果没有查询到,那么返回值应该和
src相同;如果查询到了,但是,末尾的字符比如是zz,不是关键子串key(假设关键子串为cc),那么也应该包括末尾的zz。
- 循环给
- 到这里,就得到去除关键子串之后的字符串了。但是记得
free(xtemp);,最后return dest;返回结果。
OK,看看输出吧:
char *key = "cc";
// 如果char *src = "ccaabbccddcckkccmmccppccqqccxx";
输出如下:aabbddkkmmppqqxx
// 如果char *src = "xxww";
输出如下:xxww

本文介绍了一种从源字符串中删除所有指定子串的方法,使用C语言实现,并提供了具体的代码示例。
4399

被折叠的 条评论
为什么被折叠?



