作为初学者,要学会举一反三,才能更好的掌握
今日看到一题squeeze: delete all characters stored in variable c from string s
题目很简单,删除s中的所有字符
函数接口定义:
void squeeze(char s[], int c);
裁判测试程序样例:
#include <stdio.h> void squeeze(char s[], int c); /* the length of a string */ int main(){ char s[100]; char c; int i; scanf("%s %c", s, &c); squeeze(s, c); for (i = 0; s[i] != '\0'; i++) putchar(s[i]); putchar('\n'); return 0; } /* 请在这里填写答案 */
题解:
void squeeze(char s[], int c) { int i, j; for (i = j = 0; s[i] != '\0'; ++i) if (s[i] != c) s[j++] = s[i]; s[j] = '\0'; }
但如果是删除一个子串呢?
可以用BF算法或KMP算法解决
在这里我用BF算法删除一个子串,KMP算法找到子串位置
BF算法:
#include <string.h> #include <stdio.h> int squeeze(char s1[], char s2[]); int main(){ char s1[100]; char s2[100]; int i; int index; scanf("%s %s", s1, s2); index = squeeze(s1,s2); for (i = index;i<=strlen(s2) && s1[i+strlen(s2)]!='\0';i++) { s1[i] = s1[i+strlen(s2)]; } s1[i] = '\0'; for (i = 0; s1[i] != '\0'; i++) putchar(s1[i]); putchar('\n'); return 0; } int squeeze(char s1[],char s2[]) { int i = 0,j = 0; while(i<strlen(s1) && j<strlen(s2)) { if(s1[i] == s2[j]){ ++i; ++j; } else{ i = i-j+1; j = 0;//重新指向子串第一个 } } if(j>=strlen(s2)) { return i-strlen(s2);//返回子串位置 } else return -1; }
KMP算法:
#include <string.h> #include <stdio.h> int squeeze(char s1[], char s2[]); void getnext(char s2[]); int next[50] = {0}; int main(){ char s1[100]; char s2[100]; int i; int index; scanf("%s %s", s1, s2); getnext(s2); index = squeeze(s1,s2); printf("%d",index); return 0; } int squeeze(char s1[],char s2[]) { int i = 0,j = 0; int len1,len2; len1 = strlen(s1); len2 = strlen(s2); while(i<len1 &&j<len2) { if(j==-1 || s1[i] == s2[j]) { i++; j++; } else j = next[j]; } if(j>=len2)return i-len2; else return -1; } void getnext(char s2[]) { int i = 2,j = 0; next[0] = -1; next[1] = 0; while(i<strlen(s2)) { if(j==-1 || s2[j]==s2[i-1]) { next[i] = j+1; ++i; ++j; } else j = next[j]; } }