1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
| #include <stdio.h> #include <stdlib.h> #include <string.h> #define SIZE 1000 //KMP 算法中的 next 数组 void Next(char*T,int *next) { int i=1; next[1]=0; int j=0; while (i<strlen(T)) { if (j==0||T[i-1]==T[j-1]) { i++; j++; if (T[i-1]!=T[j-1]) { next[i]=j; } else { next[i]=next[j]; } } else { j=next[j]; } } } //KMP 算法(快速模式匹配)实现函数 void KMP(char * S,char * T,int (*a)[],int *number) { int next[10]; Next(T,next);//根据模式串 T,初始化 next 数组 int i=1; int j=1; *number=0; while (i<=strlen(S)) { if (j==0 || S[i-1]==T[j-1]) { i++; j++; } else { j=next[j]; } if (j>strlen(T)) { (*number)++; (*a)[(*number)]=i-(int)strlen(T); j=0; i--; } } } //字符串替换算法,oldData:原字符串,selectData 要替换掉的字符串,数组 a 存储的是需替换字符在原字符串中的首地址,number 表示数组 a 的 长度,newData 用于存储新字符串,replace 为替换的新字符 void replaceData(char * oldData,int *a,int number,char *replace,char * selectData,char * newData) { int order=0;//表示 newData 存储字符的位置 int begin=0; for (int i=1; i<=number; i++) { //先将替换位置之前的字符完整的复制到新字符串数组中 for (int j=begin; j<a[i]-1; j++) { newData[order]=oldData[j]; order++; } //替换字符,用新字符代替 for (int k=0; k<strlen(replace); k++) { newData[order]=replace[k]; order++; } //代替完成后,计算出原字符串中隔过该字符串的下一个起始位置 begin=a[i]+(int)strlen(selectData)-1; } //要替换位置全部替换完成后,检测是否还有后续字符,若有直接复制 while(begin<strlen(oldData)) { newData[order]=oldData[begin]; order++; begin++; } } int main() { while (1) { printf("字符过滤检测系统启动(S),关闭(O),请选择:\n"); char s; char oldData[SIZE]; char selectData[SIZE]; char replace[SIZE]; char judge; char *newData=(char*)malloc(SIZE*sizeof(char)); FILE * out; scanf("%c",&s); getchar(); if (s=='O') { break; } else { printf("请输入原字符串:\n"); scanf("%[^\n]",oldData); getchar();//用于承接缓冲区冲的换行符 printf("输入要查找的字符或字符串:\n"); while (scanf("%s",selectData)) { getchar(); int a[SIZE],number; KMP(oldData,selectData,&a,&number); if (number==0) { printf("未检测到文章中有该字符串!是否重新输入(Y/N):\n"); scanf("%c",&judge); getchar(); if (judge=='N') { break; } else { printf("输入要查找的字符或字符串:\n"); } } else { printf("系统检测到该字符在原字符串中出现 %d 次,起始位置依次是:\n",number); for (int i=1; i<=number; i++) { printf("%d ",a[i]); } printf("\n"); printf("是否使用新字符串替换所有的 %s(Y/N)\n",selectData); scanf("%c",&judge); getchar(); if (judge=='Y') { printf("请输入用于替换的字符串:\n"); scanf("%[^\n]",replace); getchar(); replaceData(oldData,a,number,replace,selectData,newData); printf("新生成的字符串为: %s\n",newData); if((out=fopen("new.txt", "wr"))==NULL) { printf("新生成的字符串为%s,写入文件失败",newData); } if(fputs(newData, out)) { printf("已将新字符串写入 new.txt 文件中\n"); } free(newData); fclose(out); } break; } } } } return 0; }
|