例:在链串中,设计一个算法把最先出现的子串"ab"改为"xyz"。
解:在串s中找到最先出现的子串"ab",p指向data域值为'a'的结点,其后为data域值为'b'的结点。将它们的data域值分别改为'x'和'z',再创建一个data域值为'y'的结点,将其插入到*p之后。本例算法如下:
扩展,编写一个算法实现替换字符串(提示:查找(串的模式匹配,见下面的介绍)、替换相结合)
--------------------------------------------------------
重点:
串的模式匹配————(本人认为较难,很难很难,不过绝对值得一学,学会了有成就感
设有主串s和子串t,子串t的定位就是要在主串s中找到一个与子串t相等的子串。通常把主串s称为目标串,把子串t称为模式串,因此定位也称作模式匹配。模式匹配成功是指在目标串s中找到一个模式串t;不成功则指目标串s中不存在模式串t。
算法一:BF算法(Brute-Force)
Brute-Force简称为BF算法,亦称简单匹配算法,其基本思路是:
从目标串s="s0s1…sn-1"的第一个字符开始和模式串t="t0t1…tm-1"中的第一个字符比较,若相等,则继续逐个比较后续字符;否则从目标串s的第二个字符开始重新与模式串t的第一个字符进行比较。依次类推,若从模式串s的第i个字符开始,每个字符依次和目标串t中的对应字符相等,则匹配成功,该算法返回i;否则,匹配失败,函数返回-1。
一种实现:
二种实现:
上面这两个算法都不怎么难理解~~
关键是下面这个KMP模式匹配算法:
算法二:
如今呢我也是,似懂非懂,半懂加不懂~~~
当然里面最重要的一步就是求next数组~~~
next数组的功能是,字符串在匹配失效时,主串不用再向前做回溯操作即没有 i=i-j+1; 这步
而只对模式串做右滑操作,到底右滑多少,由next对应模式失配的下标决定。
而相应next数组的产生只取决模式自身,其证明亦很简单
关键是如何得到next数组。。。。
串的操作实现代码如下:
//串的顺序存储.. //结构体定义.. #include<stdio.h> #define MAX 100 typedef struct { char S[MAX]; }SString; //串的初始化.. void Init_Str(SString &SS) { for(int i=0;i<MAX;i++) { SS.S='\0'; //把所有值都赋'\0'.. } } //求串的长度.. int Length_Str(SString SS) { int length=0; while(SS.S[length]!='\0') //不是'\0'的话就累加起来,知道最后就知道了长度.. { length++; } return length; } //串的赋值.. void StrEvaluate(SString &SS,char S1[]) { for(int i=0;S1!='\0';i++) //这语句前面可以初始化一下SS.S[]也行.. { SS.S=S1; } } //串的链接.. void StrConcat(SString &SS,SString &S1) { int len1,len2; len1=Length_Str(SS); len2=Length_Str(S1); if(len1+len2+1<MAX) { for(int i=0;i<len2;i++) { SS.S[len1+i]=S1.S; } } else { printf("你输入的字符串长度超过了MAX!!!"); } } //求串的字串.. SString SubStr(SString &SS,int i,int length) //SS的第i个位置开始去length长的字串..然后返回.. { SString S1; Init_Str(S1); if(i+length<Length_Str(SS)) //判断字串的长度是否合法.. { for(int j=i;j<=i+length;j++) { S1.S[j-i]=SS.S[j]; } } else { printf("所取的length超出主串的长度!!!"); } return S1; } //串的比较.. int StrComp(SString S1,SString S2) { int i=0; while(S1.S==S2.S&&S1.S!='\0') //第一个元素开始判断是否相等..不相等的话来判断那个大那个小.. { i++; } if(S1.S==S2.S) { return 0; } else if(S1.S>S2.S) { return 1; } else { return -1; } } //主函数.. int main() { int k=0,len=0; SString SS,S1,S2,S3; char ch1[20]={'a','b','c','d','e','f'}; char ch2[20]={'k','l','n','m','j','k'}; char ch3,ch4,ch5,ch6,ch7,ch8,ch9; char flag=1,flag1=1; while(flag) { printf("**************************************\n"); printf("*\t1 初始化串\n"); printf("*\t2 求串的长度\n"); printf("*\t3 串的赋值\n"); printf("*\t4 串的链接\n"); printf("*\t5 求字串\n"); printf("*\t6 串的比较\n"); printf("*\t11 推出程序\n"); printf("**************************************\n"); scanf("%c",&ch3); switch(ch3) { case '1': while(flag1) { printf("\t---------------\n"); printf("-\t1. SS初始化\n"); printf("-\t2. S1初始化\n"); printf("-\t3. S2初始化\n"); printf("\t---------------\n"); scanf("%c",&ch4); switch(ch4) { case '1': Init_Str(SS); printf("SS初始化成功!"); break; case '2': Init_Str(S1); printf("S1初始化成功!"); break; case '3': Init_Str(S2); printf("S2初始化成功!"); break; case '4': flag1=0; printf("renyijian!!"); //default: } getchar(); } case '2': printf("\t---------------\n"); printf("-\t1. 求SS长度\n"); printf("-\t2. 求S1长度\n"); printf("-\t3. 求S2长度\n"); printf("\t---------------\n"); scanf("%c",&ch5); switch(ch5) { case '1': len=Length_Str(SS); printf("SS长度=%d",len); break; case '2': len=Length_Str(S1); printf("S1长度=%d",len); break; case '3': len=Length_Str(S2); printf("S2长度=%d",len); break; default: printf("changdu\n"); } case '3': while(flag) { printf("\t---------------\n"); printf("-\t1. SS赋值\n"); printf("-\t2. S1赋值\n"); printf("-\t3. S2赋值\n"); printf("\t---------------\n"); scanf("%c",&ch6); switch(ch6) { case '1': StrEvaluate(SS,ch1); printf("SS赋值成功\n!"); break; case '2': StrEvaluate(S1,ch2); printf("S1赋值成功\n!"); break; case '3': StrEvaluate(S2,ch1); printf("S2赋值成功\n!"); break; //default: //printf("fuzhi\n"); } getchar(); } case '4': printf("\t---------------\n"); printf("-\t1. SS和S1链接\n"); printf("-\t2. SS和S2链接\n"); printf("-\t3. S1和S2链接\n"); printf("\t---------------\n"); scanf("%c",&ch7); switch(ch7) { case '1': StrConcat(SS,S1); printf("SS和S1链接成功!"); break; case '2': StrConcat(SS,S2); printf("SS和S2链接成功!"); break; case '3': StrConcat(S1,S2); printf("S2和S1链接成功!"); break; default: printf("lianjie\n"); } case '5': printf("\t---------------\n"); printf("-\t1. SS的字串\n"); printf("-\t2. S1的子串\n"); printf("-\t3. S2的子串\n"); printf("\t---------------\n"); scanf("%c",&ch8); switch(ch8) { case '1': S3=SubStr(SS,3,3); break; case '2': S3=SubStr(S1,3,3); break; case '3': S3=SubStr(S2,3,3); break; default: printf("zichuan\n"); } case '6': printf("\t---------------\n"); printf("-\t1. SS和S1比较\n"); printf("-\t2. SS和S2比较\n"); printf("-\t3. S1和S2比较\n"); printf("\t---------------\n"); scanf("%c",&ch9); switch(ch9) { case '1': k=StrComp(SS,S1); printf("%d",k); printf("SS和S1比较成功!"); break; case '2': k=StrComp(SS,S2); printf("%d",k); printf("SS和S2比较成功!"); break; case '3': k=StrComp(S1,S2); printf("%d",k); printf("S2和S1比较成功!"); break; default: printf("比较\n"); } case '11': flag=0; printf("任意键结束程序.."); } getchar(); } return 0; }
作者: 李肖遥, 来源:面包板社区
链接: https://mbb.eet-china.com/blog/uid-me-3912462.html
版权声明:本文为博主原创,未经本人允许,禁止转载!
文章评论(0条评论)
登录后参与讨论