串 && KMP
来源:互联网 发布:visio数据库模型图 编辑:程序博客网 时间:2024/06/06 05:16
串
串的定义
串是由零个或多个字符组成的有限序列,又名叫字符串。一般记为
串中的字符数目n称为串的长度。
n==0的串也就是零个字符的串称为空串,长度为零,使用""
表示。
空格串,是指只包含空格的串,空格串是有长度的。
子串个数
串中任意字符的长度的子序列称为子串,子串在主串中的位置就是子串的第一个字符在主串中的序号。
长度为n的串的非空子串个数
考虑空子串的话要加一
串的操作
和线性表不同,串更关注的是查找子串的位置,得到指定位置的子串和替换子串等。
朴素的模式匹配
步骤
简单地说,就是对主串的每一个字符作为子串开头,与要匹配的字符串进行匹配。对主串做大循环,每个字符开头做T的长度的小循环,知道匹配成功或者全部遍历为止。
代码
package com.weixuan.test;public class Bunch { private static final Integer FALSE = -1; /** * @Description: 返回子串target在主串original中第i个字符之后 * @param @param * original * @param @param * target * @param @return * @return int */ public int getIndex(String original, String target) { if (original == null || original.length() <= 0) return Bunch.FALSE; if (target == null || target.length() <= 0) return Bunch.FALSE; int j = 0, i = 0; while (i < original.length() && j < target.length()) { if (original.charAt(i) == target.charAt(j)) { i++; j++; } else { /** * 后退到上次匹配的位置的下一位 */ i = i - j + 1; j = 0; } } if (j >= target.length()) return i - target.length(); return Bunch.FALSE; } public static void main(String[] args) { System.out.println(new Bunch().getIndex("abcdefg", "dbc")); }}
性能
主串长度 :M,子串长度:N
最好的情况:
平均情况:
最差情况,每次不成功的匹配都是发生在子串的最后一个字符,
KMP
next数组
S是主串,T是子串。j值的变换与主串没什么关系,j值取决于当前字符之前的串的前后缀的相似程度。
几个例子:
T = “abcdex”
a
,属于其他情况
ab
,显然a
与b
不相等,属于其他情况
abc
,显然a
与b
与c
不相等,属于其他情况
以后同理,所以T串的
2. T = “abcdex”
a
,属于其他情况
ab
,显然a
与b
不相等,属于其他情况
abc
,显然a
与b
与c
不相等,属于其他情况
abca
,前缀字符a与后缀字符相等,
abcab
,前缀字符ab
与后缀字符ab
相等,
所以T串的
3. T = “ababaaaba”
a
,属于其他情况
ab
,显然a
与b
不相等,属于其他情况
aba
,前缀与后缀相等,根据公式,
abab
,前缀字符ab
与后缀字符ab
相等,
ababa
,前缀字符aba
与后缀字符aba
相等,
ababaa
,前缀字符ab
与后缀字符aa
不相等,只有a相等,
ababaaa
,前缀字符ab
与后缀字符aa
不相等,只有a相等,
ababaaab
,前缀字符ab
与后缀字符ab
相等,
所以T串的
T = “aaaaaaaab”
a
,属于其他情况
aa
,显然a
与a
相等,
aaa
,显然前缀aa
与后缀aa
相等,
…. aaaaaaaa
,显然前缀aaaaaaa
与后缀aaaaaaa
相等,
kmp算法
public int KMP(String original, String target,int pos){ int i = pos, j = 1; int pLen = target.length(); int mLen = original.length(); char[] mChar = original.toCharArray(); /** * 模式字符串字符数组从第二个元素位置开始存放 */ char[] pChar = new char[pLen + 1]; System.arraycopy(target.toCharArray(), 0, pChar, 1, pLen); int next[] = getNextVal(target); while (i < mLen && j <= pLen) { if (j == 0 || mChar[i] == pChar[j]) { i++; j++; } else { j = next[j];// 匹配失败,回溯 } } /** * 主字符串中存在模式模式字符串 */ if (j > pLen) { /** * 返回模式字符串在主字符串中出现的位置 */ return i - pLen; } return Bunch.FALSE;}
性能
KMP算法的改进
nextval
public static int[] getNextVal(String target) { int i = 1, j = 0, len = target.length(); char[] pChar = new char[len + 1]; System.arraycopy(target.toCharArray(), 0, pChar, 1, len); int[] next = new int[len + 1]; while (i < len) { if (j == 0 || pChar[i] == pChar[j]) { i++; j++; if (pChar[i] != pChar[j]) { next[i] = j; // 设置回溯值 } else { next[i] = next[j];// 如果两个字符相等,那么将pChar[j]的回溯值复制给pChar[i] } } else { j = next[j];// 从该位置回溯 } } return next; }
nextval的具体过程
T = “ababaaaba”
所以T串的
- 串 && KMP
- kmp 子串查找
- 串和KMP算法
- KMP串匹配算法
- poj1961 kmp 重复串
- KMP串匹配算法
- kmp oj 亲和串
- 亲和串 +KMP
- KMP串匹配算法
- hdu2203亲和串(kmp)
- NYOJ327 亲和串 【KMP】
- 模式串匹配:KMP
- hdu2203 亲和串 KMP
- 串匹配(KMP)
- HDU2203 亲和串【KMP】
- HDU2203 亲和串 KMP
- 327 亲和串【kmp】
- OpenJudge_P1746 子串(KMP)
- Chapter4.1.1linux常用命令 文件处理ls ls
- Chapter4.1.2常用命令mkdir
- Action参数缓存-Spring单例
- hdu 1698 Just a Hook || 2008 “Sunline Cup” National Invitational Contest || 线段树
- Python爬虫教程——入门一之综述
- 串 && KMP
- webdriver 验证码问题 selenium_python
- Chapter4.3.1 find查找命令
- Swift开发 元组Tuple
- Python爬虫教程——入门一之爬虫基础了解
- xhprof 性能分析
- Chapter4.7邮件
- CSS float小解
- hdu 3118 Arbiter 2009武汉网络赛 图论 二分图 状压