《大话数据结构》读书笔记--第5章 串

5.2 串的定义

  1. 零个或多个字符组成的有限序列,又叫字符串。

5.3 串的比较

比较个数和 ASCII。

5.4 串的抽象数据类型

ADT
DATA
Operation 
   StrAssign(T,*chars);//生成字符串
   StrCopy(T,S);//复制 S 到 T
   ClearString(S);//清空
   StringEmpty(S);//判断是否为空
   StrLength(S);
   StrCompare(S,T);
   Concat(T,S1,S2); //合并
   SubString(Sub,S,pos,len);//切割
   Index(S,T,pos);
   Replace(S,T,V);
   StrInsert(S,pos,T);
   StrDelete(S,pos,len);

5.5 串的存储结构

5.5.1 串的顺序存储结构

  1. C 语言堆动态分配 malloc()、free()

5.5.2 串的链式存储结构

-> ABCD->IG##^
最后一个结点没有被占满,用#或其他非串值字符补全

5.6 朴素的模式匹配算法

  1. 子串的定位操作通常称做串的模式匹配
//返回子串 t 在主串 s 中第 pos 个 字符之后的位置,不存在,返回 -1
public int index(String s,String t,int pos){
   int i = pos; //从 pos 位置开始匹配 主串位置下标
   int j = 0;   //子串  子串位置下标
   //如果 i 小于主串长度 并且 t 小于子串长度
   while(i < s.length() && t < t.length()){
      //如果字符相等移动
      if(s.charAt(i) == t.charAt(j)){
         i++;
         j++;
      } else { //不相等 进行回退操作
        i = i - j + 1; 
        j = 0;  
      }
      //说明已经找到
      if(j ==  t.length()){
        return i - j; /
      } 
      return -1;
   }
}
//最好时间复杂度 O(1)
//平均  O(n+m)
//最坏  O((n-m+1) * m)

5.7 KMP模式匹配算法

  1. 当 i 和 j 位置上的字母相同时,两个指针都指向下一个位置继续比较;
  2. 当 i 和 j 位置上的字母不同时,i 不变,j 则返回到 next[j] 位置重新比较。(暂时先不管next[]的求法,只要记得定义有next[0]=-1)
  3. 当 j 返回到下标为0时,若当 i 和 j 位置上的字母仍然不同,根据(2),有 j = next[0]=-1,这时只能令 i 和 j 都继续往后移一位进行比较 (同步骤(1))
/*
 * 返回子串t在主串s中第pos个字符后的位置(包含pos位置)。若不存在返回-1
 */
public int index_KMP(String s, String t, int pos) {
    int i = pos;  //主串的指针
    int j = 0;    //子串的指针
    int[] next = getNext(t);  //获取子串的next数组
    while (i < s.length() && j < t.length()) {
       //当 j = -1 或者 字符相等移动
        if (j == -1 || s.charAt(i) == t.charAt(j)) {
        // j==-1说明了子串首位也不匹配,它是由上一步j=next[0]=-1得到的。
            i++;
            j++;
        } else {
            j = next[j];
        }
    }
    if (j == t.length()){
       return i - j;
    } 
    return -1;
}
//next[j]:当下标为 j 的元素在不匹配时,j 要跳转的下一个位置下标。
/*
 * 返回字符串的next数组
 */
public int[] getNext(String str) {
    int length = str.length();
    int[] next = new int[length]; 
    int i = 0;   //i 后缀指针
    int j = -1;  //j 前缀指针
    next[0] = -1; // 1.next[0]=-1;
    while (i < length - 1) {         // 因为后面有next[i++],所以不是i<length
        if (j == -1 || str.charAt(i) == str.charAt(j)) { // j == -1代表前后缀没有相等的部分,i+1位置的next值为0   
           //2.j==-1时,说明前缀没有与后缀相同的地方,最大长度为0,则 i+1 位置的next值只能为0,此时也可以表示为next[i+1]=j+1。当前缀中 j 位置的字符和后缀中 i 位置的字符相等时,next[i+1]=j+1         
            next[++i] = ++j;  //等于前缀的长度
        } else {
            //当 j 位置的字符和 i 位置的字符不相等时,说明前缀在第 j 个位置无法与后缀匹配,令 j 跳转到下一个匹配的位置,即 j= next[j] 。
            j = next[j];
        }
    }
    return next;
}

next[j] = j 位置前面字符串的相同前后缀的最大长度。
在这里插入图片描述

5.7.1 KMP 模式匹配算法改进

public class KMP2 {
    public int[] getNextval(String str) {
        int length = str.length();
        int[] nextval = new int[length];
        int i = 0;   //i 后缀的指针
        int j = -1;  //j 前缀的指针
        nextval[0] = -1;
        while (i < length - 1) {        
            if (j == -1 || str.charAt(i) == str.charAt(j)) {   
                i++;
                j++;
                if(str.charAt(i)!=str.charAt(j)) { //多了一个字符是否相等的判断
                    nextval[i] = j;  //等于前缀的长度
                }else {
                    nextval[i]=nextval[j];   
                }  
            } else {
                j = nextval[j];
            }
        }
        return nextval;
    }
  1. 核心:部分匹配表(Partial Match Table)的数组。PMT中的值是字符串的前缀集合与后缀集合的交集中最长元素的长度。
    如何更好的理解和掌握 KMP 算法?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值