问题定义:给定一个字符串str,以及一个关键字字符串数组key,求str中包含key中所有字符串的最短子串。
基本方法:双指针扫描字符串
详细算法:1.使用start和end两个整数来指示扫描位置。均初始化为0。
2.对end加1,直到str[start,end]中包含所有关键字,或者end>=strlen(str)
3.对start加1,直到str[start,end]中不能再包含所有的关键字。
4.若str[start,end]的长度小于上次记录的长度abstractLen,则将当前长度赋给abstractLen;
5.重复2-4步,直到end>=strlen(str);如果是第一次就满足这个条件,那说明str不能包含所有关键字,则返回NULL;否则返回查找到的子串.
代码:
#include<stdio.h>
#include<string.h>
#include<malloc.h>
int allKeyIn(char *str,char **key,int start,int end)
{
char *buf;
char **ptr=key;
if(start==end)
return 0;
buf=(char *)malloc((end-start+2)*sizeof(char));
memcpy(buf,str+start,end-start+1);
buf[end-start+1]='\0';
while(*ptr)
{
if(!strstr(buf,*ptr))
return 0;
ptr++;
}
free(buf);
return 1;
}
char *bestAbstract(char *str,char **key)
{
int start,end;
int flag=0;
int len = strlen(str);
int abstractStart=0,abstractEnd=len-1;
int abstractLen=strlen(str);
char *abstract;
start = end = 0;
while(1)
{
while(!allKeyIn(str,key,start,end)&&end<len)
end++;
while(allKeyIn(str,key,start,end))
start++;
if(end - start+2 < abstractLen)
{
abstractLen = end -start+2;
abstractStart = start-1;
abstractEnd =end;
}
if(end>=len)
{
if(!flag)
return NULL;
flag=1;
break;
}
}
abstract = (char *)malloc(sizeof(char)*(abstractLen+1));
memcpy(abstract,str+abstractStart,abstractLen);
abstract[abstractLen]='\0';
return abstract;
}
int main(void)
{
char *str="abc1deEfghiDE";
char *key[3]={"1","2",NULL};
char *abstract = bestAbstract(str,key);
if(abstract)
{
puts(abstract);
free(abstract);
}
else
printf("not all key can be found in the string\n");
return 0;
}