问题:输入一个字符串,然后输入该字符串的子串或者任意长度的字符串,将第一次出现的该字符串的子串删除,输出新的字符串,具体见示例输入输出.
sample1 input
ABCDEFG
CDE
sample1 output
ABCDEFG-CDE=ABFG
sample2 input
123456723
672
sample2 output
123456723-672=123453
- 思路一:穷举搜索,直接从第一个主串元素开始匹配,朴素版本的kmp算法,时间复杂度O(lstr*lstrsub);
- 其中lstr表示主串的长度,lstrsub子串的长度,时间效率低.
#include<stdio.h>
#include<string.h>
const int maxa=10000;
char s[maxa],sub[maxa];
void delsubstr(char *s,char *sub){
int ls=strlen(s),lsub=strlen(sub);
int cnt=0,addr=-1;
int i,j;
printf("%s-%s=",s,sub);
for(i=0;i<ls;i++){
for(j=0;j<lsub;j++){
if(sub[j]==s[i+j])
cnt++;
}
if(cnt==lsub){
addr=i;
break;
}
cnt=0;
}
if(addr==-1){
printf("不存在\n");
}else{
for(i=0;i<addr;i++)
printf("%c",s[i]);
for(i=addr+lsub;i<ls;i++)
printf("%c",s[i]);
printf("\n");
}
}
int main(){
printf("输入0 0结束程序: \n");
while(1){
scanf("%s %s",s,sub);
if(!strcmp(s,"0")&&!strcmp(sub,"0")) break;
delsubstr(s,sub);
}
return 0;
}
- 思路二:kmp算法模板求解,时间复杂度O(lstr);参考《数据结构与算法》
- 其中lstr表示主串的长度,此处时间复杂度为主串的长度,时间效率是思路一的lstrsub倍;
- 当lstrsub长度超过1e5,算法性能就有很好的体现.
#include<stdio.h> #include<string.h> const int maxa=10000; int next[maxa]; int ls,lsub; char s[maxa],sub[maxa]; void getnext(int m){ int i=0,j=-1; next[i]=-1; while(i<m){ if(j==-1||sub[i]==sub[j]){ next[++i]=++j; } else j=next[j]; } } int kmp(int pos,int lsub,int ls){ int i=pos,j=0,ans,flag=0; while(i<ls){ if(sub[j]==s[i]||j==-1){ ++i; ++j; } else j=next[j]; if(j==lsub){ ans=i; flag=1; break; } } if(flag) return ans-lsub+1; else return -1; } void delsubstr(char *s,char *sub){ int addr=kmp(0,lsub,ls); int i,j; printf("%s-%s=",s,sub); if(addr==-1) printf("不存在\n"); else{ for(i=0;i<addr-1;i++) printf("%c",s[i]); for(i=addr+lsub-1;i<ls;i++) printf("%c",s[i]); printf("\n"); } return; } int main(){ printf("输入0 0结束程序: \n"); while(1){ scanf("%s %s",s,sub); ls=strlen(s),lsub=strlen(sub); if(!strcmp(s,"0")&&!strcmp(sub,"0")) break; getnext(lsub); delsubstr(s,sub); } return 0; }