数据结构笔记(五)

一、定义

串是由零个或多个字符组成的有限序列,又名叫字符串。

  • 空格传:是只包含空格的串。是有内容有长度的,且可以有不止一个空格;
  • 子串与主串:串中任意个数的连续字符组成的子序列称为该串的子串,相应的,包含子串的串称为主串。

二、串的比较

给定两个串:s = “a1a2······an”,t = “b1b2······bm”,当满足一下条件之一时, s < t s < t s<t

1、n<m,且ai=bi(i=1,2, ······, n)。

例:当 s=“hap”,t=“happy”,就有 s<t。因为 t 比 s 多出了两个字母。

2、存在某个 k <= min(m, n),使得 ai=bi(i=1,2,······,k-1),ak<bk。

例:s=“happen”,t=“happy”,因为两串的前四个字母均相同,而两串的第 5 个字母 (k值) ,字母 e 的 ASCII 码是 101,而字母 y 的 ASCII 码是 121,显然 e<y ,所以 s<t。

三、抽象数据类型

public class String {
    void clear();
    boolean isEmpty();
    int length();
    compareToIgnoreCase(String str);
    concat(String str);
    indexOf(String str);
	repleace(String oldStr, String newStr);
}

四、存储结构

4.1、顺序存储结构

4.2、链式存储结构

五、朴素的模式匹配算法

5.1、目的

寻找一个单词在一篇文章中的定位问题。这种子串的定位操作通常称作串的模式匹配

5.2、样例说明

假设要从主串 S = “goodgoogle” 中,找到 T = “google” ,这个子串的位置。常用下列步骤来实现。

  • 主串 S 第一位开始,S 与 T 前三位均匹配成功,但 S 第四个字母是 d 而 T 的则是 g。第一次匹配失败。
  • 主串 S 第二位开始,主串 S 首字母是 o ,要匹配的 T 的首字母是 g , 匹配失败。
  • 主串 S 第三位开始,主串 S 首字母是 o ,要匹配的 T 的首字母是 g , 匹配失败。
  • 主串 S 第四位开始,主串 S 首字母是 d ,要匹配的 T 的首字母是 g , 匹配失败。
  • 主串 S 第五位开始, S 与 T ,6 个字母均匹配成功。

5.3、代码示例

int index(String s, String t, int pos) {
    int i = pos;
    int j = 1;
    while (i <= s[0] && j <= t[0]) {
        if (s[i] = t[j]) {
            ++i;
            ++j;
        } else {
            i = i-j+2;
            j = 1;
        }
    }
    if (j > t[0]) {
        return i;
    } else {
        return 0;
    }
}

六、KMP模式匹配算法

6.1、原理

如果主串 S = “abcdefgab”,要匹配的子串 T = “abcdex”,那么如果用前面的朴素算法的话,前 5 个字母,两个字符串完全相等,知道第 6 个字母, “f” 与 “x” 不等。

接下来,按照朴素模式匹配算法,应该是上图中的 2、3、4、5、6。即主串 S 中当 i = 2、3、4、5、6 时,首字符与子串T的首字符均不等。

如果我们知道 T 串中首字符 “a” 和 T 中后面的字符与 S 主串均不相等,那么后续步骤即可省略。

6.2、实现

void getNext(String t, int[] next) {
    int i=1, j=0;
    next[1]=0;
    while (i < t.length()) {
        if (j == 0 && t.charAt(i) == t.charAt(j)) {
            ++i;
            ++j;
            next[i] = j;
        } else {
            j = next[j];
        }
    }
}
int indexOf(String s, String t, int pos) {
    int i = pos;
    int j = i;
    int next = new int[255];
    getNext(t, next);
    while (i <= s.length() && j <= t.length()) {
        if (j == 0 && s.charAt(i) == t.charAt(j)) {
            ++i;
            ++j;
        } else {
            j = next[j];
        }
    }
    if (j > t.length) {
        return i-t.length();
    } else {
        return 0;
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值