Blog.3 | string:BMP、BF

int Index_BF(sstring s, sstring t, int pos)
{
 //其中,t非空,1≤pos≤StrLength(s)
 int i,j;
    i = pos-1; //下标
 j = 0; //下标
    while(i<s.length && j<t.length){
       if(s.ch[i]==t.ch[j]){++i; ++j;} //继续比较后继字符
       else{i=i-j+1; j=0;} //指针后退从新开始匹配
   }  
   if(j==t.length) return i-t.length+1; //模式串所有读完,表示匹配,返回开始匹配位置的下标
   else return 0;  
}
 

以上为BF算法的实现代码:BF算法比较“简单粗暴”,主串每次匹配失败以后都要往右移动一个单位,字串从新计数,所以其时间复杂度为O(m*n)。html

BF算法须要注意的是:算法

一、容易混淆下标与位置编程

二、对于数据容量过大的串难以进行匹配。数组

所以引入了KMP算法:学习

优势:在字串存在有相同的先后缀时,主串不回溯,模式向右滑动1个或多个位置。spa

以下表:.net

 

                                         

 

(图片来自http://www.cnblogs.com/yahong/archive/2013/11/13/3420565.html 以及晓梅老师上传的KMP讲解文件)指针

所以KMP须要添加k( k = “t1..tj-1”先后缀相等字符个数+1):当字串的第j个字符与主串的第i个字符不相等时,i不回溯,j回溯到k,即下一步对si与tk进行比较。code

而next数组存放每个j对应的k。htm

KMP算法的k值分析:

若无相等先后缀:k=1,移动t1至si。

若第一个字符就不匹配,移动t1至si+1。

其中以上分析我认为才是弄清楚kj对应关系的重点:

 

(图片来自https://www.cnblogs.com/yjiyjige/p/3263858.html)

 

 

 所以如下解释便不难理解了:

next[1]=0;
设next[j]=k,则有: 若tk=tj,则 next[j+1]=k+1 不然,k=next[k](next[k]:更小的相等先后缀长度+1),而后考虑新的tk是否等于tj : 若tk=tj,则 next[j+1]=k+1 不然,k=next[k](next[k]:更小的相等先后缀长度+1),而后考虑新的tk是否等于tj :

2、做业的收获、心得

AI做业题:

此次的做业对我来讲挑战很大,它的难点在于复杂的要求容易让人造成”想一口吃成大胖子”的编程思路,这实际上是在考验咱们的接口的编写能力(我的观点)。

分析:

一、老师在课堂上对越界的分析填补了我以前写代码的漏洞。

        char t[3001];
        int i=0;int j=0;
        for(i;isSpace(s[i]);i++)//定位到第一个非空格字符 
        //此时i已是第一个非空字符的下标 
        //特殊状况下全为空格,i为'\0'下标 
        //从i开始输入 
        while(s[i]!='\0') 
        {
            //处理状况1:单词间含有连续空格 
            if(isSpace(s[i]) && isSpace(s[i-1])) 
            {
                i++;
                continue;    
            }
       
        //越界分析:s[i-1]会不会致使越界? 
        //解释:由于进入这一步的前提是s至少有一个非空格字符。
        //第一次进入该循环时,s[i]不会等于空格,所以不会进行对s[i-1]的判断,所以不会越界。 

        //特殊状况分析:假如s[i]在最末尾的位置,且为空格
        // 解释: 可在while语句结束后加上: if(t[j-1]==' ') 
               t[j-1]='\0';
             else t[j]='\0';
检查t的最后一个字符是否空格,是则处理。

二、串和数组的灵活处理

如在定义string t时,容易发生超时等问题。由于string t没有初始化,因而没有真正地为其分配地址。那么在给t[j]赋值的时候,不会给它分配一个首地址。这就致使直接cout会出错。有两个解决办法,一个是初始化,第二个方法使用for循环遍历t串,这样就能顺利输出了,因为过于麻烦,干脆放弃用string,直接用字符数组。

    char t[3001];//注意输入所有是I的时候,输出长度是输入的三倍
    //string t;  

 

(资料分析借助https://blog.csdn.net/weixin_43314579/article/details/89217510)

3、学习内容总结,目标完成状况

一、本次做业两种算法都须要运用图解和大量模拟计算才能理解,以及题目涉及了多个条件须要考虑如何分红小接口来实现。

尽管如此,还会有不少小细节使人抓狂,因此,算法和实际代码之间的搭建桥梁的过程还须要多加熟练。

二、这周每日100行代码并无实现,而在纸上谈兵耗费了不少时间,须要提升本身的画图解的能力。

4、下周目标

一、吃透KMP算法,进一步了解pta超时的缘由。

二、每日坚持打代码(打卡提醒本身!!!)

相关文章
相关标签/搜索