串
一、定义
串是由零个或多个字符组成的有限序列,又名叫字符串。
- 空格传:是只包含空格的串。是有内容有长度的,且可以有不止一个空格;
- 子串与主串:串中任意个数的连续字符组成的子序列称为该串的子串,相应的,包含子串的串称为主串。
二、串的比较
给定两个串: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;
}
}