作为初学者,要学会举一反三,才能更好的掌握
今日看到一题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];
}
}