#include<stdio.h> #include<stdlib.h> #include<string.h> #include"SeqString.h" /*函数的声明*/ int B_FIndex(SeqString S,int pos,SeqString T,int *count); int KMP_Index(SeqString S,int pos,SeqString T,int next[],int *count); void GetNext(SeqString T,int next[]); void GetNextVal(SeqString T,int nextval[]); void PrintArray(SeqString T,int next[],int nextval[],int length); void main(){ SeqString S,T; int count1=0,count2=0,count3=0,find; int next[40],nextval[40]; StrAssign(&S,"abaababaddecab"); /*给主串S赋值*/ StrAssign(&T,"abad"); /*给模式串T赋值*/ GetNext(T,next); /*将next函数值保存在next数组*/ GetNextVal(T,nextval); /*将改进后的next函数值保存在nextval数组*/ printf("模式串T的next和改进后的next值:\n"); PrintArray(T,next,nextval,StrLength(T)); /*输出模式串T的next值与nextval值*/ find=B_FIndex(S,1,T,&count1); /*传统的模式串匹配*/ if(find>0) printf("Brute-Force算法的比较次数为:%2d\n",count1); find=KMP_Index(S,1,T,next,&count2); if(find>0) printf("利用next的KMP算法的比较次数为:%2d\n",count2); find=KMP_Index(S,1,T,nextval,&count3); if(find>0) printf("利用nextval的KMP匹配算法的比较次数为:%2d\n",count3); StrAssign(&S,"cbccccbcacbccbacbccbcbcbc"); /*给主串S赋值*/ StrAssign(&T,"cbccbcbc"); /*给模式串T赋值*/ GetNext(T,next); /*将next函数值保存在next数组*/ GetNextVal(T,nextval); /*将改进后的next函数值保存在nextval数组*/ printf("模式串T的next和改进后的next值:\n"); PrintArray(T,next,nextval,StrLength(T)); /*输出模式串T的next值域nextval值*/ find=B_FIndex(S,1,T,&count1); /*传统的模式串匹配*/ if(find>0) printf("Brute-Force算法的比较次数为:%2d\n",count1); find=KMP_Index(S,1,T,next,&count2); if(find>0) printf("利用next的KMP算法的比较次数为:%2d\n",count2); find=KMP_Index(S,1,T,nextval,&count3); if(find>0) printf("利用nextval的KMP匹配算法的比较次数为:%2d\n",count3); system("pause"); } //在主串S中的第pos个位置开始查找子串T,如果找到返回子串在主串的位置;否则,返回-1 int B_FIndex(SeqString S,int pos,SeqString T,int *count){ int i,j; i=pos-1; j=0; *count=0; //count保存主串与模式串的比较次数 while(i<S.length&&j<T.length){ if(S.str[i]==T.str[j]){ //如果串S和串T中对应位置字符相等,则继续比较下一个字符 i++; j++; }else{ //如果当前对应位置的字符不相等,则从串S的下一个字符开始,T的第0个字符开始比较 i=i-j+1; j=0; } (*count)++; } if(j>=T.length) return i-j+1; //如果在S中找到串T,则返回子串T在主串S的位置 else return -1; } //KMP模式匹配算法。利用模式串T的next函数在主串S中的第pos个位置开始查找子串T,如果找到返回子串在主串的位置;否则,返回-1 int KMP_Index(SeqString S,int pos,SeqString T,int next[],int *count){ int i,j; i=pos-1; j=0; *count=0; while(i<S.length&&j<T.length){ if(j==-1||S.str[i]==T.str[j]){ i++; j++; }else j=next[j]; (*count)++; } if(j>=T.length) return i-T.length+1; else return -1; } //求模式串T的next函数值并存入数组next void GetNext(SeqString T,int next[]){ int j,k; j=0; k=-1; next[0]=-1; while(j<T.length){ if(k==-1||T.str[j]==T.str[k]){ //如果k=-1或当前字符相等,则继续比较后面的字符并将函数值存入到next数组 j++; k++; next[j]=k; }else k=next[k]; //如果当前字符不相等,则将模式串向右移动继续比较 } } //求模式串T的next函数值的修正值并存入数组next void GetNextVal(SeqString T,int nextval[]){ int j,k; j=0; k=-1; nextval[0]=-1; while(j<T.length){ if(k==-1||T.str[j]==T.str[k]){ //如果k=-1或当前字符相等,则继续比较后面的字符并将函数值存入到nextval数组 j++; k++; if(T.str[j]!=T.str[k]) //如果所求的nextval[j]与已有的nextval[k]不相等,则将k存放在nextval中 nextval[j]=k; else nextval[j]=nextval[k]; }else //如果当前字符不相等,则将模式串向右移动继续比较 k=nextval[k]; } } //模式串T的next值与nextval值输出函数 void PrintArray(SeqString T,int next[],int nextval[],int length){ int j; printf("j:\t\t"); for(j=0;j<length;j++) printf("%3d",j); printf("\n"); printf("模式串:\t\t"); for(j=0;j<length;j++) printf("%3c",T.str[j]); printf("\n"); printf("next[j]:\t"); for(j=0;j<length;j++) printf("%3d",next[j]); printf("\n"); printf("nextval[j]:\t"); for(j=0;j<length;j++) printf("%3d",nextval[j]); printf("\n"); }
#pragma once #include<stdio.h> #include<stdlib.h> #define MaxLength 60 typedef struct{ char str[MaxLength]; int length; }SeqString; //串的赋值操作 void StrAssign(SeqString *S,char cstr[]){ int i; for(i=0;cstr[i]!='\0';i++) S->str[i]=cstr[i]; //将常量cstr中的字符赋值给串S S->length=i; } //判断串是否为空,串为空返回1,否则返回0 int StrEmpty(SeqString S){ if(S.length==0) return 1; else return 0; } //求串的长度操作 int StrLength(SeqString S){ return S.length; } //串的复制操作 void StrCopy(SeqString *T,SeqString S){ int i; for(i=0;i<S.length;i++) //将串S的字符赋值给串T T->str[i]=S.str[i]; T->length=S.length; //将串S的长度赋值给串T } //串的比较操作 int StrCompare(SeqString S,SeqString T){ //比较两个串中的字符 int i; for(i=0;i<S.length&&i<T.length;i++){ //比较两个串中的字符 if(S.str[i]!=T.str[i]) //如果出现字符不同,则返回两个字符的差值 return (S.str[i]-T.str[i]); } return (S.length-T.length); //如果比较完毕,返回两个串的长度的差值 } //串的插入操作。在S中第pos个位置插入T分为三种情况 int StrInsert(SeqString *S,int pos,SeqString T){ int i; if(pos<0||pos-1>S->length){ //插入位置不正确,返回0 printf("插入位置不正确"); return 0; } if(S->length+T.length<=MaxLength){ //第一种情况,插入子串后串长≤MaxLength,即子串T完整地插入到串S中 for(i=S->length+T.length-1;i>=pos+T.length-1;i--) //在插入子串T前,将S中pos后的字符向后移动len个位置 S->str[i]=S->str[i-T.length]; for(i=0;i<T.length;i++) //将串插入到S中 S->str[pos+i-1]=T.str[i]; S->length=S->length+T.length; return 1; }else if(pos+T.length<=MaxLength){ //第二种情况,子串可以完全插入到S中,但是S中的字符将会被截掉 for(i=MaxLength-1;i>T.length+pos-i;i--) //将S中pos以后的字符整体移动到数组的最后 S->str[i]=S->str[i-T.length]; for(i=0;i<T.length;i++) //将T插入到S中 S->str[i+pos-1]=T.str[i]; S->length=MaxLength; return 0; }else{ //第三种情况,子串T不能被完全插入到S中,T中将会有字符被舍弃 for(i=0;i<MaxLength-pos;i++) //将T直接插入到S中,插入之前不需要移动S中的字符 S->str[i+pos-1]=T.str[i]; S->length=MaxLength; return 0; } } //在串S中删除pos开始的len个字符 int StrDelete(SeqString *S,int pos,int len){ int i; if(pos<0||len<0||pos+len-1>S->length){ printf("删除位置不正确,参数len不合法"); return 0; }else{ for(i=pos+len;i<=S->length-1;i++) S->str[i-len]=S->str[i]; S->length=S->length-len; return 1; } } //串的连接操作 int StrCat(SeqString *T,SeqString S){ int i,flag; if(T->length+S.length<=MaxLength){ for(i=T->length;i<T->length+S.length;i++) T->str[i]=S.str[i-T->length]; T->length=T->length+S.length; flag=1; }else if(T->length<MaxLength){ for(i=T->length;i<MaxLength;i++) T->str[i]=S.str[i-T->length]; T->length=MaxLength; flag=0; } return flag; } //截取子串操作 int SubString(SeqString *Sub,SeqString S,int pos,int len){ int i; if(pos<0||len<0||pos+len-1>S.length){ printf("参数pos和len不合法"); return 0; }else{ for(i=0;i<len;i++) Sub->str[i]=S.str[i+pos-1]; Sub->length=len; return 1; } } //串的定位操作 int StrIndex(SeqString S,int pos,SeqString T){ int i,j; if(StrEmpty(T)) return 0; i=pos; j=0; while(i<S.length&&j<T.length){ if(S.str[i]==T.str[j]){ i++; j++; }else{ i=i-j+1; j=0; } } if(j>=T.length) return i-j+1; else return 0; } //串的替换操作 int StrReplace(SeqString *S,SeqString T,SeqString V){ //将S中所有的T替换为V int i; int flag; if(StrEmpty(T)) return 0; i=0; do{ i=StrIndex(*S,i,T);//找到T在S中的位置 if(i){ StrDelete(S,i,StrLength(T)); //删除找到的T flag=StrInsert(S,i,V); //在i位置插入V if(!flag) return 0; i+=StrLength(V); } }while(i); return 1; } //串的清空操作 void StrClear(SeqString *S){ S->length=0; } //=========== void StrPrint(SeqString S){ int i; for(i=0;i<S.length;i++){ printf("%c",S.str[i]); } printf("\n"); }
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-10-10 02:47:06