即``KMP子串大写替换主串对应位置。
有个学弟问我的,随手写写
注释还算全
#include <stdio.h>
#include <string.h>
#define max 25536
int c_next[max];
int v[max] = {0};//用于代替vector的用法
void pipixia(char *ptr);//皮皮虾函数天下第一!!!
int kmpSearch(char *a,char *b,int length1,int length2);
/*算法分析
@先匹配出那些地方从前往后按顺序可以获得子串位置
@对相应的可能错误录入进行鲁棒性处理
@生成子串的大写状态,注意不要有大写字母又-32的情况
@用生成的串替换子串在主串出现的位置
@将生成的最终final串输出到文件中
*/
void pipixia(char *ptr)//生成next的皮皮虾函数
{
int n = strlen(ptr);
int k = -1;
int i = 0;
c_next[0] = -1; //初始化第一位,以防无匹配情况
while(i < n)
{
if(k == -1 || ptr[i] == ptr[k]) // k=-1用于指针i的移动
{
i++;
k++;
c_next[i] = k;
}
else
k = c_next[k];
}
}
int kmpSearch(char *a, char *b,int length1,int length2) //匹配ab两串,a为父串
{
int i = 0, j = 0,count=0;
pipixia(b); //生成next数组
while(i < length1)
{
if(j == -1 || a[i] == b[j])
i++, j++;
else
j = c_next[j];
if(j == length2)//完全的匹配成功了
{
v[count]=i-strlen(b);//将初始位置置入vector
j = 0; //还原j的位置,初始化
count++;
}
}
return count;
}
int main ()
{
char filename[max];//文件名
char buff[max];//读取的文件主串
char sbuff[max];//录入想要读取的子串
printf("请输入字符文件名:");
scanf("%s",filename);
FILE *file1=fopen(filename,"r");
if(!file1)
{
printf("File not found.\n");
return 0;
}
fscanf(file1,"%s",buff);
printf("%s\n",buff);//测试文件是否成功读入
printf("请输入一串英文字母\n");
scanf("%s",sbuff);
/*printf("%s\n",sbuff);//测试字母是否成功读入*/
int len1 = strlen (buff);//主串长度
int len2 = strlen (sbuff);//子串长度
/*printf("%d %d\n",len1,len2);测试对应的长度是否正确录入*/
if(len1 < len2)//容错判断
{
printf("子串长于主串,不进行比较\n");
fclose(file1);//关闭文件
return 0;//退出程序
}
char Capsbuff[max];//子串字符大写
while(len2+1)
{
if(sbuff[len2]>='a'&&sbuff[len2]<='z')//如果录入的是小写字母,则将此小写字母变为大写
Capsbuff[len2]=sbuff[len2]-32;
len2--;
}
//printf("%s\n",Capsbuff );//测试是否成功转化为大写字母
//到此准备工作完成
int size = kmpSearch(buff,sbuff,len1,len2);//调用函数进行模式匹配,并求出对应v的容量
/*由于是c无法调用vector函数*/
// printf("%d\n",size );检验size是否正确
char final[max];
int p=0,q=0;
for (int i = 0; i < size ; ++i)
{
int L_next = v[i]; //取出下一个需要替换的位置
while(p < L_next)
final[q++] = buff[p++]; //将之前不需要替换的位置进行拼接
for (int j = 0; j < (int) strlen(Capsbuff); ++j)
final[q++] = Capsbuff[j]; //替换掉字符串
p += strlen(sbuff); //重新置位置
}
while(p<(int) strlen(buff)) //将最后的也放进去
final[q++] = buff[p++];
final[q]=0;
//puts(final);//测试用控制台显示
//printf("一共替换了%d次!\n", size);检验替换次数
/*写入文件*/
printf("请输入输出文件名:");
scanf("%s",filename);
FILE *file2=fopen(filename,"w+");
fputs(final,file2);
printf("写入%s文件成功\n",filename);
fclose(file2);
fclose(file1);
return 0;
}